Giter VIP home page Giter VIP logo

l8w8jwt's Introduction

l8w8jwt

Codacy Codecov CircleCI License Shield API Docs

Icon

l8w8jwt (say "lightweight jawt") is a minimal, OpenSSL-less and super lightweight JWT library written in C.

Its only significant dependency (in terms of heaviness) is ARM's open-source MbedTLS library.

The others are extremely lightweight header-only libraries for JSON handling and building strings.

ᐳᐳ Check out the API docs here on github.io

How to clone

git clone --recursive https://github.com/GlitchedPolygons/l8w8jwt.git

Make sure to do a recursive clone, otherwise you need to git submodule update --init --recursive at a later point!

How to use

Just add l8w8jwt as a git submodule to your project (e.g. into some lib/ or deps/ folder inside your project's repo; {repo_root}/lib/ is used here in the following example).

git submodule add https://github.com/GlitchedPolygons/l8w8jwt.git lib/l8w8jwt
git submodule update --init --recursive

If you don't want to use git submodules, you can also start vendoring a specific version of l8w8jwt by copying its full repo content into the folder where you keep your project's external libraries/dependencies.

Building and linking

If you use CMake you can just add_subdirectory(path_to_git_submodule) and then target_link_libraries(your_project PRIVATE l8w8jwt) inside your CMakeLists.txt file.

If you use GCC, check out this issue's log here.

For devices with a particularly small stack, please define the L8W8JWT_SMALL_STACK pre-processor definition and set it to 1.

Build shared library/DLL

bash build.sh

If the build succeeds, you should have a new .tar.gz file inside the build/ directory.

This command works on Windows too: just use the Git Bash for Windows CLI!

NOTE: If you use the l8w8jwt shared library in your project on Windows, remember to #define L8W8JWT_DLL 1 before including any of the l8w8jwt headers! Maybe even set it as a pre-processor definition. Otherwise the headers won't have the necessary __declspec(dllimport) declarations!

MinGW on Windows

bash build-mingw.sh

Run this using e.g. "Git Bash for Windows". Make sure that you have your MinGW installation directory inside your PATH - otherwise this script will fail when trying to call mingw32-make.exe.

Official release builds are made using mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/bin/gcc.exe.

Build static library

mkdir -p build && cd build
cmake -DBUILD_SHARED_LIBS=Off -DL8W8JWT_PACKAGE=On -DCMAKE_BUILD_TYPE=Release ..
cmake --build . --config Release

NOTE: When compiling l8w8jwt as a static lib, remember to link against the MbedTLS libs too! Those will be placed inside the build/mbedtls/library/ directory after successful compilation.

Examples

Encoding and signing a token

#include "l8w8jwt/encode.h"

int main(void)
{
    char* jwt;
    size_t jwt_length;

    struct l8w8jwt_encoding_params params;
    l8w8jwt_encoding_params_init(&params);

    params.alg = L8W8JWT_ALG_HS512;

    params.sub = "Gordon Freeman";
    params.iss = "Black Mesa";
    params.aud = "Administrator";

    params.iat = time(NULL);
    params.exp = time(NULL) + 600; /* Set to expire after 10 minutes (600 seconds). */

    params.secret_key = (unsigned char*)"YoUR sUpEr S3krEt 1337 HMAC kEy HeRE";
    params.secret_key_length = strlen(params.secret_key);

    params.out = &jwt;
    params.out_length = &jwt_length;

    int r = l8w8jwt_encode(&params);

    printf("\n l8w8jwt example HS512 token: %s \n", r == L8W8JWT_SUCCESS ? jwt : " (encoding failure) ");

    /* Always free the output jwt string! */
    l8w8jwt_free(jwt);

    return 0;
}

Decoding and verifying a token

#include "l8w8jwt/decode.h"

static const char KEY[] = "YoUR sUpEr S3krEt 1337 HMAC kEy HeRE";
static const char JWT[] = "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE1ODA5MzczMjksImV4cCI6MTU4MDkzNzkyOSwic3ViIjoiR29yZG9uIEZyZWVtYW4iLCJpc3MiOiJCbGFjayBNZXNhIiwiYXVkIjoiQWRtaW5pc3RyYXRvciJ9.7oNEgWxzs4nCtxOgiyTofP2bxZtL8dS7hgGXRPPDmwQWN1pjcwntsyK4Y5Cr9035Ro6Q16WOLiVAbj7k7TeCDA";

int main(void)
{
    struct l8w8jwt_decoding_params params;
    l8w8jwt_decoding_params_init(&params);

    params.alg = L8W8JWT_ALG_HS512;

    params.jwt = (char*)JWT;
    params.jwt_length = strlen(JWT);

    params.verification_key = (unsigned char*)KEY;
    params.verification_key_length = strlen(KEY);

    /* 
     * Not providing params.validate_iss_length makes it use strlen()
     * Only do this when using properly NUL-terminated C-strings! 
     */
    params.validate_iss = "Black Mesa"; 
    params.validate_sub = "Gordon Freeman";

    /* Expiration validation set to false here only because the above example token is already expired! */
    params.validate_exp = 0; 
    params.exp_tolerance_seconds = 60;

    params.validate_iat = 1;
    params.iat_tolerance_seconds = 60;

    enum l8w8jwt_validation_result validation_result;

    int decode_result = l8w8jwt_decode(&params, &validation_result, NULL, NULL);

    if (decode_result == L8W8JWT_SUCCESS && validation_result == L8W8JWT_VALID) 
    {
        printf("\n Example HS512 token validation successful! \n");
    }
    else
    {
        printf("\n Example HS512 token validation failed! \n");
    }
    
    /*
     * decode_result describes whether decoding/parsing the token succeeded or failed;
     * the output l8w8jwt_validation_result variable contains actual information about
     * JWT signature verification status and claims validation (e.g. expiration check).
     * 
     * If you need the claims, pass an (ideally stack pre-allocated) array of struct l8w8jwt_claim
     * instead of NULL,NULL into the corresponding l8w8jwt_decode() function parameters.
     * If that array is heap-allocated, remember to free it yourself!
     */

    return 0;
}

More examples can be found inside this repo's examples/ folder - check them out now and find out how to encode/decode custom claims and sign using the various asymmetric algos!

Mandatory parameters

Some encoding/decoding parameters can be omitted, while others can't.

Here is the overview of minimal required parameters that can't be omitted for encoding and decoding JWTs:

Encode
Decode

EdDSA

L8w8jwt supports the EdDSA signing algorithm. The Ed25519 curve is used. By default it is turned off though (to avoid a potentially unnecessary dependency to the Ed25519 library inside lib/ed25519).

To turn it on, define the compiler pre-processor definition L8W8JWT_ENABLE_EDDSA (set it to 1 to enable it).

Correspondingly, for shared library usage, you'd need to build the l8w8jwt DLL/.so yourself, since the pre-built binary available on the Releases page is built without it!

=> For CMake, to do so you'd just need to pass -DL8W8JWT_ENABLE_EDDSA=On to the CMake command before building!

For generating the keys, you should use the library that is also used by l8w8jwt for signing and verifying JWT signatures: lib/ed25519 (a fork of ORLP's ed25519, kudos to Orson Peters for writing this great and super-simple C lib!). It's inside this repo's lib/ folder as a git submodule.

Note for the key parameter

  • When using the HS256, HS384 and HS512 signing algorithms (symmetric), the l8w8jwt key parameter is the HMAC secret.
  • For the RS256, RS384, RS512, PS256, PS384 and PS512 signature algos it's the PEM-formatted RSA key string.
  • ES256 => PEM-formatted NIST P-256 key.
  • ES384 => PEM-formatted NIST P-384 key.
  • ES512 => PEM-formatted NIST P-521 key.
  • ES256K => PEM-formatted secp256k1 key.
  • EdDSA => Hex-encoded Ed25519 key string (Ref10 format)
    • For Ed25519 signing specifically, the private key must be in the Ref10 Ed25519 format: exactly like the ones you'd get out of libsodium, NaCl, SUPERCOP, ...
    • Check out the l8w8jwt EdDSA examples for more information and demo usage!

To find out how you would go about generating these keys, check out the examples/: there's comments at the top of those files containing the commands that were used for key generation.


View on jwt.io

l8w8jwt's People

Contributors

glitchedpolygons avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.