END_TEST START_TEST(test_jwt_encode_alg_none) { const char res[] = "eyJhbGciOiJub25lIn0.eyJhdWQiOiJ3d3cucGx1Z2dlcnM" "ubmwiLCJleHAiOjE0Nzc1MTQ4MTIsInN1YiI6IlBsdWdnZXJzIFNvZnR3YXJlIn0."; jwt_t *jwt = NULL; int ret = 0; char *out; ALLOC_JWT(&jwt); ret = jwt_add_grant(jwt, "aud", "www.pluggers.nl"); ck_assert_int_eq(ret, 0); ret = jwt_add_grant_int(jwt, "exp", 1477514812); ck_assert_int_eq(ret, 0); ret = jwt_add_grant(jwt, "sub", "Pluggers Software"); ck_assert_int_eq(ret, 0); ret = jwt_set_alg(jwt, JWT_ALG_NONE, NULL, 0); ck_assert_int_eq(ret, 0); out = jwt_encode_str(jwt); ck_assert_ptr_ne(out, NULL); ck_assert_str_eq(out, res); free(out); jwt_free(jwt); }
/** * Calculates a Java Web Token (JWT) given the path to a EC private key and * Google Cloud project ID. Returns the JWT as a string that the caller must * free. */ static char* CreateJwt(const char* ec_private_path, const char* project_id) { char iat_time[sizeof(time_t) * 3 + 2]; char exp_time[sizeof(time_t) * 3 + 2]; uint8_t* key = NULL; // Stores the Base64 encoded certificate size_t key_len = 0; jwt_t *jwt = NULL; int ret = 0; char *out = NULL; // Read private key from file FILE *fp = fopen(ec_private_path, "r"); if (fp == (void*) NULL) { printf("Could not open file: %s\n", ec_private_path); return ""; } fseek(fp, 0L, SEEK_END); key_len = ftell(fp); fseek(fp, 0L, SEEK_SET); key = malloc(sizeof(uint8_t) * (key_len + 1)); // certificate length + \0 fread(key, 1, key_len, fp); key[key_len] = '\0'; fclose(fp); // Get JWT parts GetIatExp(iat_time, exp_time, sizeof(iat_time)); jwt_new(&jwt); // Write JWT ret = jwt_add_grant(jwt, "iat", iat_time); if (ret) { printf("Error setting issue timestamp: %d", ret); } ret = jwt_add_grant(jwt, "exp", exp_time); if (ret) { printf("Error setting expiration: %d", ret); } ret = jwt_add_grant(jwt, "aud", project_id); if (ret) { printf("Error adding audience: %d", ret); } ret = jwt_set_alg(jwt, JWT_ALG_ES256, key, key_len); if (ret) { printf("Error during set alg: %d", ret); } out = jwt_encode_str(jwt); // Print JWT if (TRACE) { printf("JWT: [%s]", out); } jwt_free(jwt); free(key); return out; }
END_TEST START_TEST(test_jwt_encode_change_alg) { const char res[] = "eyJhbGciOiJub25lIn0.eyJpYXQiOjE0NzU5ODA1NDUsIm" "lzcyI6ImZpbGVzLmN5cGhyZS5jb20iLCJyZWYiOiJYWFhYLVlZWVktWlpa" "Wi1BQUFBLUNDQ0MiLCJzdWIiOiJ1c2VyMCJ9."; unsigned char key512[64] = "012345678901234567890123456789XY" "012345678901234567890123456789XY"; jwt_t *jwt = NULL; int ret = 0; char *out; ALLOC_JWT(&jwt); ret = jwt_add_grant(jwt, "iss", "files.cyphre.com"); ck_assert_int_eq(ret, 0); ret = jwt_add_grant(jwt, "sub", "user0"); ck_assert_int_eq(ret, 0); ret = jwt_add_grant(jwt, "ref", "XXXX-YYYY-ZZZZ-AAAA-CCCC"); ck_assert_int_eq(ret, 0); ret = jwt_add_grant_int(jwt, "iat", TS_CONST); ck_assert_int_eq(ret, 0); ret = jwt_set_alg(jwt, JWT_ALG_HS512, key512, sizeof(key512)); ck_assert_int_eq(ret, 0); ret = jwt_set_alg(jwt, JWT_ALG_NONE, NULL, 0); ck_assert_int_eq(ret, 0); out = jwt_encode_str(jwt); ck_assert_ptr_ne(out, NULL); ck_assert_str_eq(out, res); free(out); jwt_free(jwt); }
END_TEST START_TEST(test_jwt_encode_invalid) { unsigned char key512[64] = "012345678901234567890123456789XY" "012345678901234567890123456789XY"; jwt_t *jwt = NULL; int ret = 0; ALLOC_JWT(&jwt); ret = jwt_add_grant(jwt, "iss", "files.cyphre.com"); ck_assert_int_eq(ret, 0); ret = jwt_add_grant(jwt, "sub", "user0"); ck_assert_int_eq(ret, 0); ret = jwt_add_grant(jwt, "ref", "XXXX-YYYY-ZZZZ-AAAA-CCCC"); ck_assert_int_eq(ret, 0); ret = jwt_add_grant_int(jwt, "iat", TS_CONST); ck_assert_int_eq(ret, 0); ret = jwt_set_alg(jwt, JWT_ALG_HS512, NULL, 0); ck_assert_int_eq(ret, EINVAL); ret = jwt_set_alg(jwt, JWT_ALG_HS512, NULL, sizeof(key512)); ck_assert_int_eq(ret, EINVAL); ret = jwt_set_alg(jwt, JWT_ALG_HS512, key512, 0); ck_assert_int_eq(ret, EINVAL); ret = jwt_set_alg(jwt, JWT_ALG_NONE, key512, sizeof(key512)); ck_assert_int_eq(ret, EINVAL); ret = jwt_set_alg(jwt, JWT_ALG_NONE, key512, 0); ck_assert_int_eq(ret, EINVAL); ret = jwt_set_alg(jwt, JWT_ALG_NONE, NULL, sizeof(key512)); ck_assert_int_eq(ret, EINVAL); /* Set a value that will never happen. */ ret = jwt_set_alg(jwt, 999, NULL, 0); ck_assert_int_eq(ret, EINVAL); jwt_free(jwt); }
END_TEST START_TEST(test_jwt_encode_hs512) { const char res[] = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJpYXQiOj" "E0NzU5ODA1NDUsImlzcyI6ImZpbGVzLmN5cGhyZS5jb20iLCJyZWYiOiJY" "WFhYLVlZWVktWlpaWi1BQUFBLUNDQ0MiLCJzdWIiOiJ1c2VyMCJ9.EETPP" "pt4ViWccjHExKKyS-WPVtsvFTMVCl3WniLGdw_ZwGwXAEZ5ujf4cjmt1DU" "akpemETBfFDEFsKaFA7ApjA"; unsigned char key512[64] = "012345678901234567890123456789XY" "012345678901234567890123456789XY"; jwt_t *jwt = NULL; int ret = 0; char *out; ALLOC_JWT(&jwt); ret = jwt_add_grant(jwt, "iss", "files.cyphre.com"); ck_assert_int_eq(ret, 0); ret = jwt_add_grant(jwt, "sub", "user0"); ck_assert_int_eq(ret, 0); ret = jwt_add_grant(jwt, "ref", "XXXX-YYYY-ZZZZ-AAAA-CCCC"); ck_assert_int_eq(ret, 0); ret = jwt_add_grant_int(jwt, "iat", TS_CONST); ck_assert_int_eq(ret, 0); ret = jwt_set_alg(jwt, JWT_ALG_HS512, key512, sizeof(key512)); ck_assert_int_eq(ret, 0); out = jwt_encode_str(jwt); ck_assert_ptr_ne(out, NULL); ck_assert_str_eq(out, res); free(out); jwt_free(jwt); }
END_TEST START_TEST(test_jwt_encode_hs384) { const char res[] = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9.eyJpYXQi" "OjE0NzU5ODA1NDUsImlzcyI6ImZpbGVzLmN5cGhyZS5jb20iLCJyZWYi" "OiJYWFhYLVlZWVktWlpaWi1BQUFBLUNDQ0MiLCJzdWIiOiJ1c2VyMCJ9" ".Iu3GemfZo8eJX78QtgNXgYvb0KLo8_TsZskjivx8tc4jJ1-KhFpDtOr" "W4KYBFspI"; unsigned char key384[48] = "aaaabbbbccccddddeeeeffffgggghhhh" "iiiijjjjkkkkllll"; jwt_t *jwt = NULL; int ret = 0; char *out; ALLOC_JWT(&jwt); ret = jwt_add_grant(jwt, "iss", "files.cyphre.com"); ck_assert_int_eq(ret, 0); ret = jwt_add_grant(jwt, "sub", "user0"); ck_assert_int_eq(ret, 0); ret = jwt_add_grant(jwt, "ref", "XXXX-YYYY-ZZZZ-AAAA-CCCC"); ck_assert_int_eq(ret, 0); ret = jwt_add_grant_int(jwt, "iat", TS_CONST); ck_assert_int_eq(ret, 0); ret = jwt_set_alg(jwt, JWT_ALG_HS384, key384, sizeof(key384)); ck_assert_int_eq(ret, 0); out = jwt_encode_str(jwt); ck_assert_ptr_ne(out, NULL); ck_assert_str_eq(out, res); free(out); jwt_free(jwt); }
END_TEST START_TEST(test_jwt_encode_hs256) { const char res[] = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE0NzU" "5ODA1NDUsImlzcyI6ImZpbGVzLmN5cGhyZS5jb20iLCJyZWYiOiJYWFhYLVlZWV" "ktWlpaWi1BQUFBLUNDQ0MiLCJzdWIiOiJ1c2VyMCJ9.ldP-njT746Qv9MihQmuy" "_CgNg64lKywpBgkDxkkfkAs"; unsigned char key256[32] = "012345678901234567890123456789XY"; jwt_t *jwt = NULL; int ret = 0; char *out; ALLOC_JWT(&jwt); ret = jwt_add_grant(jwt, "iss", "files.cyphre.com"); ck_assert_int_eq(ret, 0); ret = jwt_add_grant(jwt, "sub", "user0"); ck_assert_int_eq(ret, 0); ret = jwt_add_grant(jwt, "ref", "XXXX-YYYY-ZZZZ-AAAA-CCCC"); ck_assert_int_eq(ret, 0); ret = jwt_add_grant_int(jwt, "iat", TS_CONST); ck_assert_int_eq(ret, 0); ret = jwt_set_alg(jwt, JWT_ALG_HS256, key256, sizeof(key256)); ck_assert_int_eq(ret, 0); out = jwt_encode_str(jwt); ck_assert_ptr_ne(out, NULL); ck_assert_str_eq(out, res); free(out); jwt_free(jwt); }
/** * @brief can be used to build a jwt for a user * * @param user a user model * @return a jwt token as string */ std::string AuthenticationApp::buildJWT (cppcms::http::response & resp, const model::User & user) const { jwt_t * jwt; // reserve token memory if (jwt_new (&jwt) != 0 || !jwt) { RootApp::setInternalServerError (resp, "Something went wrong while creating the session token.", "AUTH_CREATE_TOKEN_ERROR"); throw exception::JwtCreationException (); } // create smart pointer that ensures freeing the jwt std::unique_ptr<jwt_t, void (*) (jwt_t *)> jwt_ptr (jwt, jwt_free); // specify jwt algorithm and encryption key if (jwt_set_alg (jwt_ptr.get (), JWT_ALG_HS256, reinterpret_cast<const unsigned char *> ( Config::instance ().getConfig ().get<std::string> ("jwt.encryption.secret").c_str ()), Config::instance ().getConfig ().get<std::string> ("jwt.encryption.secret").size ()) != 0) { RootApp::setInternalServerError (resp, "Something went wrong while creating the session token.", "AUTH_CREATE_TOKEN_ERROR"); throw exception::JwtCreationException (); } // add claims if (jwt_add_grant (jwt_ptr.get (), "issuer", ELEKTRA_REST_AUTHENTICATION_JWT_ISSUER) != 0 || jwt_add_grant (jwt_ptr.get (), "username", user.getUsername ().c_str ()) != 0 || jwt_add_grant_int (jwt_ptr.get (), "rank", user.getRank ()) != 0 || jwt_add_grant_int (jwt_ptr.get (), "expires", std::time (NULL) + Config::instance ().getConfig ().get<int> ("jwt.validity")) != 0) { RootApp::setInternalServerError (resp, "Something went wrong while creating the session token.", "AUTH_CREATE_TOKEN_ERROR"); throw exception::JwtCreationException (); } // generate and return token return std::string (jwt_encode_str (jwt_ptr.get ())); }