update for cross compile

This commit is contained in:
wt
2024-12-02 04:01:55 +07:00
parent 8accbdc476
commit e89bc07659
127 changed files with 238 additions and 15518 deletions
+1
View File
@@ -1,4 +1,5 @@
build
bin
.vscode
.idea
cmake-build-debug
+2 -3
View File
@@ -1,11 +1,10 @@
cmake_minimum_required (VERSION 2.6)
project(auth_service)
set(CMAKE_CXX_COMPILER /home/tola/Documents/linux/orangepipc/buildroot-2024.08.2/output/host/bin/arm-buildroot-linux-uclibcgnueabihf-g++)
set(CMAKE_CXX_STANDARD 17)
include_directories(./src/libs/)
add_subdirectory(./src/libs/jwt-cpp-0.7.0)
add_executable(
auth_service
src/auth_service.cpp
@@ -24,6 +23,6 @@ add_executable(
src/security/cors.cpp
)
target_link_libraries(auth_service jwt-cpp::jwt-cpp)
target_link_libraries(auth_service ssl crypto)
install(TARGETS auth_service DESTINATION bin)
+20
View File
@@ -0,0 +1,20 @@
CXX=g++
CXXFLAGS=-Wall -l ssl -l crypto -I src/libs -I src/auth -I src/security -I src/users
SOURCES=src/auth_service.cpp src/auth/auth.cpp src/auth/verify_auth.cpp src/security/cors.cpp src/users/access_request.cpp src/users/add_user.cpp src/users/change_password.cpp src/users/change_user.cpp src/users/delete_user.cpp src/users/get_all_users.cpp src/users/get_user.cpp
TARGET=bin/auth_service
default: all
all: build
build:
@if [ ! -d bin ]; then \
mkdir bin; \
fi
$(CXX) -o $(TARGET) $(SOURCES) $(CXXFLAGS)
clean:
@if [ -f $(TARGET) ]; then \
rm -v $(TARGET); \
fi
+12 -7
View File
@@ -1,7 +1,7 @@
#include "auth.hpp"
#include "../colors.h"
#include "../includes.hpp"
#include <jwt-cpp/jwt.h>
#include <jwt.hpp>
#include <syslog.h>
// function for authorization users
@@ -44,15 +44,20 @@ void auth(const httplib::Request &request, httplib::Response &response) {
syslog(LOG_ERR, "auth request rejected");
return;
}
nlohmann::json headers = {
{"alg", "HS256"},
{"typ", "JWT"}
};
std::string token = jwt::create()
.set_type("JWT")
.set_issuer("auth0")
.set_payload_claim("userId", jwt::claim(userid))
.sign(jwt::algorithm::hs256{JWT_SECRET_KEY});
nlohmann::json payload {
{"userId", userid}
};
std::string token = JWT::createJWT(headers.dump(), payload.dump(), JWT_DEFAULT_SECRET);
std::stringstream response_json;
response_json << R"({"token":")" << token << "\"}";
response_json << R"({"token":")" << token.c_str() << "\"}";
syslog(LOG_INFO, "auth request success");
response.set_content(response_json.str(), JSON_TYPE);
}
+1 -4
View File
@@ -1,5 +1,4 @@
#ifndef AUTH_HPP
#define AUTH_HPP
#pragma once
#include <httplib.h>
#include <json.hpp>
@@ -9,5 +8,3 @@ void auth(const httplib::Request &request, httplib::Response &response);
// function for verify tokens
bool verify_auth(const std::string &token);
#endif // AUTH_HPP
+2 -11
View File
@@ -1,21 +1,12 @@
#include "auth.hpp"
#include <jwt-cpp/jwt.h>
#include <jwt.hpp>
#include "../includes.hpp"
#include <syslog.h>
// function for verify tokens
bool verify_auth(const std::string &token) {
try {
// parse token
const jwt::decoded_jwt<jwt::traits::kazuho_picojson> decoded = jwt::decode(token);
// validate token
const jwt::verifier<jwt::default_clock, jwt::traits::kazuho_picojson> verifier = jwt::verify()
.allow_algorithm(jwt::algorithm::hs256{JWT_SECRET_KEY})
.with_issuer("auth0");
verifier.verify(decoded);
return true;
return JWT::verifyJWT(token, JWT_DEFAULT_SECRET);
} catch (const std::system_error &e) {
std::cout << "Verification error: " << e.what() << std::endl;
syslog(LOG_ERR, "token verification error");
-22
View File
@@ -1,22 +0,0 @@
BasedOnStyle: LLVM
BreakBeforeBraces: Attach
ColumnLimit: 120 # Match GitHub UI
UseTab: Always
TabWidth: 4
IndentWidth: 4
AccessModifierOffset: -4
ContinuationIndentWidth: 4
NamespaceIndentation: All
IndentCaseLabels: false
PointerAlignment: Left
AlwaysBreakTemplateDeclarations: Yes
SpaceAfterTemplateKeyword: false
AllowShortCaseLabelsOnASingleLine: true
AllowShortIfStatementsOnASingleLine: WithoutElse
AllowShortBlocksOnASingleLine: Always
FixNamespaceComments: true
ReflowComments: false
-41
View File
@@ -1,41 +0,0 @@
Checks: '-*,
bugprone-*,
cert-*,
clang-analyzer-*,
clang-diagnostic-*,
-clang-diagnostic-c++17-extensions,
google-*,
-google-runtime-references,
-google-readability-braces-around-statements,
hicpp-*,
-hicpp-braces-around-statements,
-hicpp-signed-bitwise,
misc-*,
-misc-non-private-member-variables-in-classes,
llvm-*,
modernize-*,
-modernize-use-trailing-return-type,
performance-*,
portability-*,
readability-*,
-readability-magic-numbers,
-readability-braces-around-statements,
-readability-uppercase-literal-suffix'
CheckOptions:
- key: readability-identifier-naming.TypedefCase
value: lower_case
- key: readability-identifier-naming.StructCase
value: lower_case
- key: readability-identifier-naming.ClassCase
value: lower_case
- key: readability-identifier-naming.VariableCase
value: lower_case
- key: readability-identifier-naming.ParameterCase
value: lower_case
- key: readability-identifier-naming.FunctionCase
value: lower_case
- key: readability-identifier-naming.NamespaceCase
value: lower_case
- key: readability-identifier-naming.GlobalConstantCase
value: lower_case
-208
View File
@@ -1,208 +0,0 @@
# ----------------------------------
# Options affecting listfile parsing
# ----------------------------------
with section("parse"):
# Specify structure for custom cmake functions
additional_commands = { 'foo': { 'flags': ['BAR', 'BAZ'],
'kwargs': {'DEPENDS': '*', 'HEADERS': '*', 'SOURCES': '*'}}}
# -----------------------------
# Options effecting formatting.
# -----------------------------
with section("format"):
# How wide to allow formatted cmake files
line_width = 120
# How many spaces to tab for indent
tab_size = 2
# If an argument group contains more than this many sub-groups (parg or kwarg
# groups) then force it to a vertical layout.
max_subgroups_hwrap = 12
# If a positional argument group contains more than this many arguments, then
# force it to a vertical layout.
max_pargs_hwrap = 24
# If true, separate flow control names from their parentheses with a space
separate_ctrl_name_with_space = False
# If true, separate function names from parentheses with a space
separate_fn_name_with_space = False
# If a statement is wrapped to more than one line, than dangle the closing
# parenthesis on its own line.
dangle_parens = False
# If the trailing parenthesis must be 'dangled' on its on line, then align it
# to this reference: `prefix`: the start of the statement, `prefix-indent`:
# the start of the statement, plus one indentation level, `child`: align to
# the column of the arguments
dangle_align = 'prefix'
# If the statement spelling length (including space and parenthesis) is
# smaller than this amount, then force reject nested layouts.
min_prefix_chars = 4
# If the statement spelling length (including space and parenthesis) is larger
# than the tab width by more than this amount, then force reject un-nested
# layouts.
max_prefix_chars = 10
# If a candidate layout is wrapped horizontally but it exceeds this many
# lines, then reject the layout.
max_lines_hwrap = 12
# What style line endings to use in the output.
line_ending = 'unix'
# Format command names consistently as 'lower' or 'upper' case
command_case = 'lower'
# Format keywords consistently as 'lower' or 'upper' case
keyword_case = 'upper'
# A list of command names which should always be wrapped
always_wrap = []
# If true, the argument lists which are known to be sortable will be sorted
# lexicographicall
enable_sort = True
# If true, the parsers may infer whether or not an argument list is sortable
# (without annotation).
autosort = False
# By default, if cmake-format cannot successfully fit everything into the
# desired linewidth it will apply the last, most agressive attempt that it
# made. If this flag is True, however, cmake-format will print error, exit
# with non-zero status code, and write-out nothing
require_valid_layout = False
# A dictionary mapping layout nodes to a list of wrap decisions. See the
# documentation for more information.
layout_passes = {}
# ------------------------------------------------
# Options affecting comment reflow and formatting.
# ------------------------------------------------
with section("markup"):
# What character to use for bulleted lists
bullet_char = '*'
# What character to use as punctuation after numerals in an enumerated list
enum_char = '.'
# If comment markup is enabled, don't reflow the first comment block in each
# listfile. Use this to preserve formatting of your copyright/license
# statements.
first_comment_is_literal = False
# If comment markup is enabled, don't reflow any comment block which matches
# this (regex) pattern. Default is `None` (disabled).
literal_comment_pattern = None
# Regular expression to match preformat fences in comments
# default=r'^\s*([`~]{3}[`~]*)(.*)$'
fence_pattern = '^\\s*([`~]{3}[`~]*)(.*)$'
# Regular expression to match rulers in comments
# default=r'^\s*[^\w\s]{3}.*[^\w\s]{3}$'
ruler_pattern = '^\\s*[^\\w\\s]{3}.*[^\\w\\s]{3}$'
# If a comment line matches starts with this pattern then it is explicitly a
# trailing comment for the preceeding argument. Default is '#<'
explicit_trailing_pattern = '#<'
# If a comment line starts with at least this many consecutive hash
# characters, then don't lstrip() them off. This allows for lazy hash rulers
# where the first hash char is not separated by space
hashruler_min_length = 10
# If true, then insert a space between the first hash char and remaining hash
# chars in a hash ruler, and normalize its length to fill the column
canonicalize_hashrulers = True
# enable comment markup parsing and reflow
enable_markup = True
# ----------------------------
# Options affecting the linter
# ----------------------------
with section("lint"):
# a list of lint codes to disable
disabled_codes = []
# regular expression pattern describing valid function names
function_pattern = '[0-9a-z_]+'
# regular expression pattern describing valid macro names
macro_pattern = '[0-9A-Z_]+'
# regular expression pattern describing valid names for variables with global
# scope
global_var_pattern = '[0-9A-Z][0-9A-Z_]+'
# regular expression pattern describing valid names for variables with global
# scope (but internal semantic)
internal_var_pattern = '_[0-9A-Z][0-9A-Z_]+'
# regular expression pattern describing valid names for variables with local
# scope
local_var_pattern = '[0-9a-z_]+'
# regular expression pattern describing valid names for privatedirectory
# variables
private_var_pattern = '_[0-9a-z_]+'
# regular expression pattern describing valid names for publicdirectory
# variables
public_var_pattern = '[0-9A-Z][0-9A-Z_]+'
# regular expression pattern describing valid names for keywords used in
# functions or macros
keyword_pattern = '[0-9A-Z_]+'
# In the heuristic for C0201, how many conditionals to match within a loop in
# before considering the loop a parser.
max_conditionals_custom_parser = 2
# Require at least this many newlines between statements
min_statement_spacing = 1
# Require no more than this many newlines between statements
max_statement_spacing = 1
max_returns = 6
max_branches = 12
max_arguments = 5
max_localvars = 15
max_statements = 50
# -------------------------------
# Options effecting file encoding
# -------------------------------
with section("encode"):
# If true, emit the unicode byte-order mark (BOM) at the start of the file
emit_byteorder_mark = False
# Specify the encoding of the input file. Defaults to utf-8
input_encoding = 'utf-8'
# Specify the encoding of the output file. Defaults to utf-8. Note that cmake
# only claims to support utf-8 so be careful when using anything else
output_encoding = 'utf-8'
# -------------------------------------
# Miscellaneous configurations options.
# -------------------------------------
with section("misc"):
# A dictionary containing any per-command configuration overrides. Currently
# only `command_case` is supported.
per_command = {}
-17
View File
@@ -1,17 +0,0 @@
root = true
[!*.{h,cpp}]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.{h,cpp}]
indent_style = tab
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
-17
View File
@@ -1,17 +0,0 @@
# Auto detect text files and perform LF normalization
* text=auto
# Custom for Visual Studio
*.cs diff=csharp
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain
-2
View File
@@ -1,2 +0,0 @@
github: [Thalhammer,prince-chrismc]
patreon: Thalhammer
@@ -1,83 +0,0 @@
name: Bug Report 🐛
description: File a bug report
labels: ["bug"]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this bug report!
validations:
required: false
- type: textarea
id: what-happened
attributes:
label: What happened?
description: Also tell us, what did you expect to happen? Feel free to include some screenshots
placeholder: Tell us what you see!
value: "A bug happened!"
validations:
required: true
- type: textarea
id: reproduce
attributes:
label: How To Reproduce?
description: Please provide a small snippet to reproduce the issue
placeholder: Some C++ code or Shell code to recreate th problem
value: |
```c++
#include "jwt-cpp/jwt.h"
int main() {
return 0;
}
```
- type: dropdown
id: version
attributes:
label: Version
description: What version of our software are you running?
options:
- 0.7.0
- 0.6.0
- 0.5.2
- Older (please let us know if the "What happened" box)
validations:
required: true
- type: dropdown
id: operating-system
attributes:
label: What OS are you seeing the problem on?
multiple: true
options:
- Windows
- Linux
- MacOS
- Other (please let us know if the "What happened" box)
validations:
required: true
- type: dropdown
id: compiler
attributes:
label: What compiler are you seeing the problem on?
multiple: true
options:
- GCC
- Clang
- MSVC
- Other (please let us know if the "What happened" box)
validations:
required: true
- type: textarea
id: logs
attributes:
label: Relevant log output
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
render: shell
- type: checkboxes
id: terms
attributes:
label: Code of Conduct
description: By submitting this issue, you agree to follow our [Code of Conduct](https://example.com)
options:
- label: I agree to follow this project's Code of Conduct
required: true
@@ -1,20 +0,0 @@
name: Feature Request 🧪
description: Have a great idea? Find something is missing?
labels: ["enhancement"]
body:
- type: markdown
attributes:
value: |
We'd love to hear your idea(s)!
- type: input
id: question
attributes:
label: "What would you like to see added?"
validations:
required: true
- type: textarea
id: context
attributes:
label: Additional Context
validations:
required: true
@@ -1,20 +0,0 @@
name: Support Question 🤹
description: Have some questions? We can offer help.
labels: ["question"]
body:
- type: markdown
attributes:
value: |
Don't hesitate to ask any question you might have!
- type: input
id: question
attributes:
label: "What's your question?"
validations:
required: true
- type: textarea
id: context
attributes:
label: Additional Context
validations:
required: true
-31
View File
@@ -1,31 +0,0 @@
name: Regular badging sequence
description: Publishes a badge based on the job status
inputs:
category:
description: The subfolder where to group the badges
required: true
label:
description: The label to you in the badge (this should be unique for each badge in a category)
required: true
github_token:
description: The token to use to publish the changes
required: false
default: ${{ github.token }}
runs:
using: composite
steps:
- if: job.status == 'success'
uses: ./.github/actions/badge/write
with:
category: ${{ inputs.category }}
label: ${{ inputs.label }}
- if: job.status == 'failure'
uses: ./.github/actions/badge/write
with:
category: ${{ inputs.category }}
label: ${{ inputs.label }}
message: Failing
color: red
- uses: ./.github/actions/badge/publish
with:
github_token: ${{ inputs.github_token }}
@@ -1,24 +0,0 @@
name: Make a Badge
description: Creates a JSON file for use with Sheilds.io. The default is a "brightgreen" "Passing" badge
inputs:
category:
description: The subfolder where to group the badges
required: true
label:
description: The label to you in the badge (this should be unqie for each badge in a category)
required: true
message:
description: The message you wish to have in the badge
required: false
default: "Passing"
color:
description: The color you wish the badge to be
required: false
default: "brightgreen"
runs:
using: composite
steps:
- run: |
mkdir -p badges/${{ inputs.category }}/${{ inputs.label }}
echo '{ "schemaVersion": 1, "label": "${{ inputs.label }}", "message": "${{ inputs.message }}", "color": "${{ inputs.color }}" }' > badges/${{ inputs.category }}/${{ inputs.label }}/shields.json
shell: bash
@@ -1,17 +0,0 @@
name: Install Boost.JSON
description: Install Boost.JSON for building test application
inputs:
version:
description: The desired Boost.JSON version to install
required: false
default: "1.78.0"
runs:
using: composite
steps:
- run: |
cd /tmp
wget https://github.com/boostorg/json/archive/boost-${{ inputs.version }}.tar.gz
tar -zxf /tmp/boost-${{ inputs.version }}.tar.gz
cd json-boost-${{ inputs.version }}
sudo cp -vR include/boost /usr/local/include
shell: bash
@@ -1,39 +0,0 @@
name: Install CMake
description: Download, Build and Cache CMake
inputs:
version:
description: The desired CMake version to install
required: true
url:
description: "The corresponding URL to download the source code from"
required: true
runs:
using: composite
steps:
- name: Cache CMake
id: cache-cmake
uses: actions/cache@v3
with:
path: cmake-${{ inputs.version }}
key: ${{ runner.name }}-${{ runner.os }}-${{ runner.arch }}-cmake-${{ inputs.version }}
- name: Build cmake
if: steps.cache-cmake.outputs.cache-hit != 'true'
run: |
wget ${{ inputs.url }}
tar -zxf cmake-${{ inputs.version }}.tar.gz
cd cmake-${{ inputs.version }}
./bootstrap
make -j $(nproc)
shell: bash
- name: Install cmake
run: |
cd cmake-${{ inputs.version }}
# Depending if we run in on a GitHub Actions or from within a Docker image we have different permissions
if [[ $EUID > 0 ]]; then
# If we are not root then we need to sudo
sudo make install
else
# Default docker image does not have users setup so we are only root and can not sudo
make install
fi
shell: bash
@@ -1,18 +0,0 @@
name: Install jsoncons
description: Install jsoncons for building test application
inputs:
version:
description: The desired jsoncons version to install
required: false
default: "0.168.7"
runs:
using: composite
steps:
- run: |
cd /tmp
wget https://github.com/danielaparker/jsoncons/archive/v${{ inputs.version }}.tar.gz
tar -zxf /tmp/v${{ inputs.version }}.tar.gz
cd jsoncons-${{ inputs.version }}
cmake .
sudo cmake --install .
shell: bash
@@ -1,15 +0,0 @@
name: Install GTest
description: Install and setup GTest for linking and building test application
runs:
using: composite
steps:
- run: sudo apt-get install libgtest-dev lcov
shell: bash
- run: (cd /usr/src/gtest && sudo `which cmake` .)
shell: bash
- run: sudo make -j $(nproc) -C /usr/src/gtest
shell: bash
- run: sudo ln -s /usr/src/gtest/libgtest.a /usr/lib/libgtest.a
shell: bash
- run: sudo ln -s /usr/src/gtest/libgtest_main.a /usr/lib/libgtest_main.a
shell: bash
@@ -1,17 +0,0 @@
name: Install PicoJSON
description: Install PicoJSON for building test application
inputs:
version:
description: The desired PicoJSON version to install
required: false
default: "v1.3.0"
runs:
using: composite
steps:
- run: |
cd /tmp
wget https://github.com/kazuho/picojson/archive/${{ inputs.version }}.tar.gz
tar -zxf /tmp/${{ inputs.version }}.tar.gz
cd picojson-${{ inputs.version }}
sudo cp -v picojson.h /usr/local/include/picojson
shell: bash
@@ -1,19 +0,0 @@
name: Install LibreSSL
description: Install and setup LibreSSL for linking and building test application
inputs:
version:
description: The desired LibreSSL version to install
required: false
default: "3.3.0"
runs:
using: composite
steps:
- run: |
wget https://raw.githubusercontent.com/libressl-portable/portable/v${{ inputs.version }}/FindLibreSSL.cmake -P cmake/
cd /tmp
wget https://ftp.openbsd.org/pub/OpenBSD/LibreSSL/libressl-${{ inputs.version }}.tar.gz
tar -zvxf /tmp/libressl-${{ inputs.version }}.tar.gz
cd libressl-${{ inputs.version }}
./configure
sudo make -j $(nproc) install
shell: bash
@@ -1,18 +0,0 @@
name: Install nlohmann-json
description: Install nlohmann-json for building test application
inputs:
version:
description: The desired nlohmann-json version to install
required: false
default: "3.11.2"
runs:
using: composite
steps:
- run: |
cd /tmp
wget https://github.com/nlohmann/json/archive/v${{ inputs.version }}.tar.gz
tar -zxf /tmp/v${{ inputs.version }}.tar.gz
cd json-${{ inputs.version }}
cmake .
sudo cmake --install .
shell: bash
@@ -1,19 +0,0 @@
name: Install OpenSSL
description: Install and setup OpenSSL for linking and building test application
inputs:
version:
description: The desired OpenSSL version to install
required: false
default: "openssl-3.0.0"
runs:
using: composite
steps:
- run: |
cd /tmp
wget https://github.com/openssl/openssl/archive/refs/tags/${{ inputs.version }}.tar.gz
tar -zxf /tmp/${{ inputs.version }}.tar.gz
cd openssl-${{ inputs.version }}
./config --prefix=/tmp --libdir=lib
make -j $(nproc)
sudo make -j $(nproc) install_sw
shell: bash
@@ -1,22 +0,0 @@
name: Install wolfSSL
description: Install and setup wolfSSL for linking and building test application
inputs:
version:
description: The desired stable wolfSSL version to install
required: false
default: "v4.8.1-stable"
runs:
using: composite
steps:
- run: |
cd /tmp
wget -O wolfssl.tar.gz https://github.com/wolfSSL/wolfssl/archive/${{ inputs.version }}.tar.gz
tar -zxf /tmp/wolfssl.tar.gz
cd wolfssl-*
autoreconf -fiv
./configure --enable-opensslall --enable-opensslextra --disable-examples --disable-crypttests --enable-harden --enable-all --enable-all-crypto
make
sudo make install
shell: bash
- run: sudo rm -rf /usr/include/openssl
shell: bash
@@ -1,26 +0,0 @@
name: Process Linting Results
description: Add a comment to a pull request with when `git diff` present and save the changes as an artifact so they can be applied manually
inputs:
linter_name:
description: The name of the tool to credit in the comment
required: true
runs:
using: "composite"
steps:
- run: git add --update
shell: bash
- id: stage
#continue-on-error: true
uses: Thalhammer/patch-generator-action@v2
# Unfortunately the previous action reports a failure so nothing else can run
# partially a limitation on composite actions since `continue-on-error` is not
# yet supported
- if: steps.stage.outputs.result == 'dirty'
uses: actions-ecosystem/action-create-comment@v1
with:
github_token: ${{ github.token }}
body: |
Hello, @${{ github.actor }}! `${{ inputs.linter_name }}` had some concerns :scream:
- run: exit $(git status -uno -s | wc -l)
shell: bash
@@ -1,52 +0,0 @@
name: "Render `defaults.h` Template"
description: "Generate the `defaults.h` header file for a JSON library"
inputs:
traits_name:
description: "Name of the traits structure to be used. Typically in the format `author_repository` or equivilant"
required: true
library_name:
description: "Name of the JSON library."
required: true
library_url:
description: "URL to the JSON library."
required: true
disable_default_traits:
description: "Set the macro to disable the default traits"
required: false
default: "true"
runs:
using: composite
steps:
- uses: actions/setup-node@v3
with:
node-version: 14
- run: npm install mustache
shell: bash
- uses: actions/github-script@v6
env:
TRAITS_NAME: ${{ inputs.traits_name }}
LIBRARY_NAME: ${{ inputs.library_name }}
LIBRARY_URL: ${{ inputs.library_url }}
DISABLE_DEFAULT_TRAITS: ${{ inputs.disable_default_traits }}
with:
script: |
const mustache = require('mustache')
const path = require('path')
const fs = require('fs')
const { TRAITS_NAME, LIBRARY_NAME, LIBRARY_URL, DISABLE_DEFAULT_TRAITS } = process.env
console.log(`Rendering ${TRAITS_NAME}!`)
const disableDefault = DISABLE_DEFAULT_TRAITS === 'true'
const template = fs.readFileSync(path.join('include', 'jwt-cpp', 'traits', 'defaults.h.mustache'), 'utf8')
const content = mustache.render(template, {
traits_name: TRAITS_NAME,
traits_name_upper: TRAITS_NAME.toUpperCase(),
library_name: LIBRARY_NAME,
library_url: LIBRARY_URL,
disable_default_traits: disableDefault,
})
const outputDir = path.join('include', 'jwt-cpp', 'traits', TRAITS_NAME.replace('_', '-'))
fs.mkdirSync(outputDir, { recursive: true })
fs.writeFileSync(path.join(outputDir, 'defaults.h'), content)
@@ -1,39 +0,0 @@
name: "Render `TraitsTests.cpp` Template"
description: "Generate the `TraitsTests.cpp` header file for a JSON library"
inputs:
traits_name:
description: "Name of the traits structure to be used. Typically in the format `author_repository` or equivilant"
required: true
test_suite_name:
description: "Name of the JSON library."
required: true
runs:
using: composite
steps:
- uses: actions/setup-node@v3
with:
node-version: 14
- run: npm install mustache
shell: bash
- uses: actions/github-script@v6
env:
TRAITS_NAME: ${{ inputs.traits_name }}
SUITE_NAME: ${{ inputs.test_suite_name }}
with:
script: |
const mustache = require('mustache')
const path = require('path')
const fs = require('fs')
const { TRAITS_NAME, SUITE_NAME } = process.env
console.log(`Rendering ${TRAITS_NAME}!`)
const template = fs.readFileSync(path.join('tests', 'traits', 'TraitsTest.cpp.mustache'), 'utf8')
const content = mustache.render(template, {
traits_name: TRAITS_NAME,
traits_dir: TRAITS_NAME.replace('_', '-'),
test_suite_name: SUITE_NAME,
})
const outputDir = path.join('tests', 'traits')
fs.mkdirSync(outputDir, { recursive: true })
fs.writeFileSync(path.join(outputDir, `${SUITE_NAME}.cpp`), content)
-16
View File
@@ -1,16 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<svg viewBox="0 0 2450 750" width="2450" height="750" xmlns="http://www.w3.org/2000/svg">
<g style="" transform="matrix(1.01, 0, 0, 1, 550, 140)">
<path d="M -551.881 -175.95 L 1948.119 -175.95 L 1948.119 609.368 L -551.881 609.368 Z" clip-rule="evenodd" fill-rule="evenodd" style=""/>
<path d="M -108.039 81.534 L -108.639 -86.566 L -202.439 -86.566 L -201.839 81.534 L -154.939 145.934 Z M -201.839 369.634 L -201.839 538.334 L -108.039 538.334 L -108.039 369.634 L -154.939 305.234 Z" fill="#fff" clip-rule="evenodd" fill-rule="evenodd"/>
<path d="M -108.039 369.634 L -9.239 505.934 L 66.361 450.934 L -32.439 314.634 L -108.039 290.234 Z M -201.839 81.534 L -301.239 -54.766 L -376.839 0.234 L -278.039 136.434 L -201.839 160.834 Z" clip-rule="evenodd" fill-rule="evenodd" style="fill: rgb(101, 154, 210);"/>
<path d="M -278.039 136.534 L -438.039 84.634 L -466.839 173.334 L -306.839 225.834 L -231.239 200.834 Z M -79.339 250.234 L -32.439 314.634 L 127.561 366.534 L 156.361 277.834 L -3.639 225.934 Z" fill="#00b9f1" clip-rule="evenodd" fill-rule="evenodd"/>
<path d="M -3.739 225.934 L 156.261 173.434 L 127.461 84.734 L -32.539 136.634 L -79.439 201.034 Z M -306.839 225.934 L -466.839 277.834 L -438.039 366.534 L -278.039 314.634 L -231.139 250.234 Z" clip-rule="evenodd" fill-rule="evenodd" style="fill: rgb(0, 89, 156);"/>
<path d="M -278.039 314.634 L -376.839 450.934 L -301.239 505.934 L -201.839 369.634 L -201.839 290.234 Z M -32.439 136.534 L 66.361 0.234 L -9.239 -54.766 L -108.039 81.434 L -108.039 160.834 Z" clip-rule="evenodd" fill-rule="evenodd" style="fill: rgb(0, 68, 130);"/>
<path d="M 343.623 72.734 L 343.623 291.434 C 343.623 339.534 304.223 378.934 256.123 378.934 L 256.123 335.134 C 280.523 335.134 299.923 315.734 299.923 291.334 L 299.923 72.734 Z M 1142.423 116.534 L 1241.123 116.534 L 1241.123 72.834 L 1000.523 72.834 L 1000.523 116.534 L 1098.623 116.534 L 1098.623 379.034 L 1142.423 379.034 Z M 868.623 72.734 L 868.623 291.434 C 868.623 315.834 849.223 335.234 824.823 335.234 C 800.423 335.234 781.023 315.834 781.023 291.434 L 781.023 160.234 C 781.023 112.134 741.623 72.734 693.523 72.734 C 645.423 72.734 606.023 112.134 606.023 160.234 L 606.023 291.534 C 606.023 315.934 586.623 335.334 562.223 335.334 C 537.823 335.334 518.423 315.934 518.423 291.534 L 518.423 72.734 L 474.623 72.734 L 474.623 291.434 C 474.623 339.534 514.023 378.934 562.123 378.934 C 610.223 378.934 649.623 339.534 649.623 291.434 L 649.623 160.234 C 649.623 135.834 669.023 116.434 693.423 116.434 C 717.823 116.434 737.223 135.834 737.223 160.234 L 737.223 291.534 C 737.223 339.634 776.623 379.034 824.723 379.034 C 872.823 379.034 912.223 339.634 912.223 291.534 L 912.223 72.734 Z" fill="#fff" clip-rule="evenodd" fill-rule="evenodd"/>
<g transform="matrix(6.824428, -0.018276, 0.018773, 7.009964, -218.175049, -971.69281)" style="">
<polygon fill="#FFFFFF" points="255 168.508 241.666 168.508 241.666 155.175 234.334 155.175 234.334 168.508 221 168.508 221 175.841 234.334 175.841 234.334 189.175 241.666 189.175 241.666 175.841 255 175.841"/>
<polygon fill="#FFFFFF" points="297.5 168.508 284.166 168.508 284.166 155.175 276.834 155.175 276.834 168.508 263.5 168.508 263.5 175.841 276.834 175.841 276.834 189.175 284.166 189.175 284.166 175.841 297.5 175.841"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.3 KiB

-19
View File
@@ -1,19 +0,0 @@
@media (prefers-color-scheme: dark) {
table.markdownTable, table.fieldtable {
width: auto;
}
html:not(.light-mode) {
/* define dark-mode variable overrides here if you DON'T use doxygen-awesome-darkmode-toggle.js */
}
html:not(.light-mode) div.contents table img {
filter: none;
}
html:not(.light-mode) div.qindex,
html:not(.light-mode) div.navtab {
background-color: var(--side-nav-background);
border: 1px solid var(--separator-color);
}
}
-21
View File
@@ -1,21 +0,0 @@
# Reporting Security Issues
If you believe you have found a security vulnerability in JWT-CPP, we encourage you to let us know right away.
We will investigate all legitimate reports and do our best to quickly fix the problem.
Please refer to the section below for our responsible disclosure policy:
## Disclosure Policy
Please contact one or more of the maintainers using the email advertised on our GitHub profiles:
- [@Thalhammer](https://github.com/Thalhammer)
- [@prince-chrismc](https://github.com/prince-chrismc)
Please provide as many details as possible about version, platform, and workflow as possible.
Having steps and reproducible code is better and is always greatly appreciated.
## Supported Version
Typically, fixes will be immediately released as a new patch release. However, older affected versions may receive
a new patch upon request.
-233
View File
@@ -1,233 +0,0 @@
name: CMake CI
on:
push:
branches: [master]
pull_request:
branches: [master]
paths:
- "CMakeLists.txt"
- "cmake/**"
- "include/jwt-cpp/**"
- "tests/cmake/**"
- ".github/actions/**"
- ".github/workflows/cmake.yml"
jobs:
default-linux:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: lukka/get-cmake@latest
- name: setup
run: |
mkdir build
cd build
cmake .. -DJWT_BUILD_EXAMPLES=OFF
sudo make install
- name: test
run: |
cd tests/cmake
cmake . -DTEST:STRING="defaults-enabled" -DCMAKE_FIND_DEBUG_MODE=1
cmake --build .
default-linux-with-examples:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: lukka/get-cmake@latest
- name: setup
run: |
mkdir build
cd build
cmake ..
sudo cmake --install .
- name: test
run: |
cd tests/cmake
cmake . -DTEST:STRING="defaults-enabled"
cmake --build .
default-win:
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
- uses: lukka/get-cmake@latest
- run: choco install openssl
- name: setup
run: |
cmake -E make_directory build
cd build
cmake .. -DJWT_BUILD_EXAMPLES=OFF
cmake --install .
- name: test
run: |
cd tests/cmake
cmake . -DTEST:STRING="defaults-enabled" -DCMAKE_FIND_DEBUG_MODE=1
cmake --build .
min-req:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/install/cmake
with:
version: "3.14.7"
url: "https://cmake.org/files/v3.14/cmake-3.14.7.tar.gz"
- uses: ./.github/actions/install/gtest
- name: setup
run: |
mkdir build
cd build
cmake .. -DJWT_BUILD_EXAMPLES=ON -DJWT_BUILD_TESTS=ON
sudo make install
- name: test
run: |
cd tests/cmake
cmake . -DTEST:STRING="defaults-enabled"
cmake --build .
custom-install-linux:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: lukka/get-cmake@latest
- name: setup
run: |
mkdir build
cd build
cmake .. -DCMAKE_INSTALL_PREFIX:STRING="/opt/jwt-cpp" -DJWT_BUILD_EXAMPLES=OFF
make install
- name: test
run: |
cd tests/cmake
cmake . -DCMAKE_PREFIX_PATH="/opt/jwt-cpp" -DTEST:STRING="defaults-enabled" -DCMAKE_FIND_DEBUG_MODE=1
cmake --build .
custom-install-win:
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
- uses: lukka/get-cmake@latest
- run: choco install openssl
- name: setup
run: |
cmake -E make_directory build
cd build
cmake .. -DCMAKE_INSTALL_PREFIX:STRING="C:/jwt-cpp" -DJWT_BUILD_EXAMPLES=OFF
cmake --install .
- name: test
run: |
cd tests/cmake
cmake . -DCMAKE_PREFIX_PATH="C:/jwt-cpp" -DTEST:STRING="defaults-enabled" -DCMAKE_FIND_DEBUG_MODE=1
cmake --build .
no-pico:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: lukka/get-cmake@latest
- name: setup
run: |
mkdir build
cd build
cmake .. -DJWT_DISABLE_PICOJSON=ON -DJWT_BUILD_EXAMPLES=OFF
sudo make install
- name: test
run: |
cd tests/cmake
cmake . -DCMAKE_PREFIX_PATH=/usr/local/cmake -DTEST:STRING="picojson-is-disabled"
cmake --build .
no-base64:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: lukka/get-cmake@latest
- name: setup
run: |
mkdir build
cd build
cmake .. -DJWT_DISABLE_BASE64=ON -DJWT_BUILD_EXAMPLES=OFF
sudo make install
- name: test
run: |
cd tests/cmake
cmake . -DCMAKE_PREFIX_PATH=/usr/local/cmake -DTEST:STRING="base64-is-disabled"
cmake --build .
with-libressl:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: lukka/get-cmake@latest
- uses: ./.github/actions/install/libressl
- name: setup
run: |
mkdir build
cd build
cmake .. -DJWT_SSL_LIBRARY:STRING="LibreSSL" -DJWT_BUILD_EXAMPLES=OFF
sudo make install
- name: test
run: |
cd tests/cmake
cmake . -DCMAKE_PREFIX_PATH=/usr/local/cmake -DCMAKE_MODULE_PATH=../../cmake -DTEST:STRING="libressl-is-used"
cmake --build .
with-wolfssl:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: lukka/get-cmake@latest
- uses: ./.github/actions/install/wolfssl
with:
version: ab3bbf11e9d39b52e24bf42bbc6babc16d4a669b
- name: setup
run: |
mkdir build
cd build
cmake .. -DJWT_SSL_LIBRARY:STRING="wolfSSL" -DJWT_BUILD_EXAMPLES=OFF
sudo make install
- name: test
run: |
cd tests/cmake
cmake . -DTEST:STRING="wolfssl-is-used"
cmake --build .
with-hunter:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: lukka/get-cmake@latest
- name: setup
run: |
mkdir build
cd build
cmake .. -DJWT_BUILD_TESTS=ON -DJWT_BUILD_EXAMPLES=ON -DJWT_ENABLE_COVERAGE=OFF -DHUNTER_ENABLED=ON
make
- name: test
run: |
cd build
./tests/jwt-cpp-test
@@ -1,54 +0,0 @@
name: Cross-Platform CI
on:
push:
branches: [master]
pull_request:
branches: [master]
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [macos-latest, windows-latest, ubuntu-latest]
steps:
- if: matrix.os == 'windows-latest'
run: choco install openssl
- if: matrix.os == 'macos-latest'
run: sudo cp /usr/local/opt/openssl@1.1/lib/pkgconfig/*.pc /usr/local/lib/pkgconfig/
- uses: actions/checkout@v3
- run: cmake -E make_directory ${{ github.workspace }}/build
- name: configure
shell: bash # access regardless of the host operating system
working-directory: ${{ github.workspace }}/build
run: cmake $GITHUB_WORKSPACE -DJWT_BUILD_EXAMPLES=ON
- name: build
working-directory: ${{ github.workspace }}/build
shell: bash
run: cmake --build .
- if: matrix.os != 'windows-latest'
name: test
working-directory: ${{ github.workspace }}/build
shell: bash
run: |
./example/rsa-create
./example/rsa-verify
- if: matrix.os == 'windows-latest'
name: test
working-directory: ${{ github.workspace }}/build
run: |
example\Debug\rsa-create.exe
example\Debug\rsa-verify.exe
- if: github.event_name == 'push' && always()
uses: ./.github/actions/badge
with:
category: cross-platform
label: ${{ matrix.os }}
@@ -1,21 +0,0 @@
name: Documentation CI
on:
push:
branches: [master]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: sudo apt install graphviz
- run: wget https://raw.githubusercontent.com/jothepro/doxygen-awesome-css/v1.6.1/doxygen-awesome.css
- run: wget https://raw.githubusercontent.com/jothepro/doxygen-awesome-css/v1.6.1/doxygen-awesome-sidebar-only.css
- uses: mattnotmitt/doxygen-action@v1
- name: deploy
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./doxy/html
force_orphan: true
-104
View File
@@ -1,104 +0,0 @@
name: JWT CI
on:
push:
branches: [master]
pull_request:
branches: [master]
jobs:
coverage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: lukka/get-cmake@latest
- uses: ./.github/actions/install/gtest
- uses: ./.github/actions/install/danielaparker-jsoncons
- uses: ./.github/actions/install/boost-json
- name: configure
run: |
mkdir build
cd build
cmake .. -DJWT_BUILD_EXAMPLES=OFF -DJWT_BUILD_TESTS=ON -DJWT_ENABLE_COVERAGE=ON -DCMAKE_BUILD_TYPE=Debug
- name: run
working-directory: build
run: make jwt-cpp-test coverage
- uses: coverallsapp/github-action@1.1.3
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
path-to-lcov: build/coverage.info
fuzzing:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: lukka/get-cmake@latest
- uses: ./.github/actions/install/gtest
- name: configure
run: |
mkdir build
cd build
cmake .. -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DJWT_ENABLE_FUZZING=ON
- name: run
working-directory: build
run: |
make jwt-cpp-fuzz-BaseEncodeFuzz jwt-cpp-fuzz-BaseDecodeFuzz jwt-cpp-fuzz-TokenDecodeFuzz
./tests/fuzz/jwt-cpp-fuzz-BaseEncodeFuzz -runs=100000
./tests/fuzz/jwt-cpp-fuzz-BaseDecodeFuzz -runs=100000 ../tests/fuzz/decode-corpus
./tests/fuzz/jwt-cpp-fuzz-TokenDecodeFuzz -runs=100000 ../tests/fuzz/token-corpus
asan: ## Based on https://gist.github.com/jlblancoc/44be9d4d466f0a973b1f3808a8e56782
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
- uses: lukka/get-cmake@latest
- uses: ./.github/actions/install/gtest
- name: configure
run: |
mkdir build
cd build
cmake .. -DJWT_BUILD_TESTS=ON -DCMAKE_CXX_FLAGS="-fsanitize=address -fsanitize=leak -g" \
-DCMAKE_C_FLAGS="-fsanitize=address -fsanitize=leak -g" \
-DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address -fsanitize=leak" \
-DCMAKE_MODULE_LINKER_FLAGS="-fsanitize=address -fsanitize=leak"
- name: run
working-directory: build
run: |
make
export ASAN_OPTIONS=check_initialization_order=true:detect_stack_use_after_return=true:fast_unwind_on_malloc=0
./example/rsa-create
./example/rsa-verify
./tests/jwt-cpp-test
ubsan:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
- uses: lukka/get-cmake@latest
- uses: ./.github/actions/install/gtest
- name: configure
run: |
mkdir build
cd build
cmake .. -DJWT_BUILD_TESTS=ON -DCMAKE_CXX_STANDARD=20 \
-DCMAKE_CXX_FLAGS="-fsanitize=undefined -fsanitize=return -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fno-sanitize-recover=all -g" \
-DCMAKE_C_FLAGS="-fsanitize=undefined -fsanitize=return -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fno-sanitize-recover=all -g" \
-DCMAKE_EXE_LINKER_FLAGS="-fsanitize=undefined -fsanitize=return -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fno-sanitize-recover=all" \
-DCMAKE_MODULE_LINKER_FLAGS="-fsanitize=undefined -fsanitize=return -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fno-sanitize-recover=all"
- name: run
working-directory: build
run: |
make
export UBSAN_OPTIONS=print_stacktrace=1
./example/rsa-create
./example/rsa-verify
./tests/jwt-cpp-test
-123
View File
@@ -1,123 +0,0 @@
name: Lint CI
on:
push:
branches: [master]
pull_request:
branches: [master]
jobs:
clang-format:
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
files:
- "include/jwt-cpp/*.h"
- "include/jwt-cpp/traits/**/*.h"
- "tests/*.cpp"
- "tests/**/*.cpp"
- "example/*.cpp"
- "example/**/*.cpp"
steps:
- run: |
sudo apt-get install clang-format-14
shopt -s globstar
- uses: actions/checkout@v3
- run: clang-format-14 -i ${{ matrix.files }}
- uses: ./.github/actions/process-linting-results
with:
linter_name: clang-format
cmake-format:
runs-on: ubuntu-20.04
strategy:
fail-fast: false
matrix:
files: ["**/CMakeLists.txt", "cmake/code-coverage.cmake"]
steps:
- uses: actions/setup-python@v2
with:
python-version: "3.x"
- run: pip install cmakelang
- run: shopt -s globstar
- uses: actions/checkout@v3
- run: cmake-format -i ${{ matrix.files }}
- uses: ./.github/actions/process-linting-results
with:
linter_name: cmake-format
clang-tidy:
runs-on: ubuntu-20.04
steps:
- run: sudo apt-get install clang-tidy
- uses: lukka/get-cmake@latest
- uses: actions/checkout@v3
- name: configure
run: |
mkdir build
cd build
cmake .. -DCMAKE_CXX_CLANG_TIDY="clang-tidy;-fix"
- name: run
working-directory: build
run: make
- uses: ./.github/actions/process-linting-results
with:
linter_name: clang-tidy
render-defaults:
runs-on: ubuntu-20.04
strategy:
fail-fast: false
matrix:
traits:
- { name: "boost_json", library: "Boost.JSON", url: "https://github.com/boostorg/json", disable_pico: true }
- { name: "danielaparker_jsoncons", library: "jsoncons", url: "https://github.com/danielaparker/jsoncons", disable_pico: true }
- { name: "kazuho_picojson", library: "picojson", url: "https://github.com/kazuho/picojson", disable_pico: false }
- { name: "nlohmann_json", library: "JSON for Modern C++", url: "https://github.com/nlohmann/json", disable_pico: true }
name: render-defaults (${{ matrix.traits.name }})
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/render/defaults
with:
traits_name: ${{ matrix.traits.name }}
library_name: ${{ matrix.traits.library }}
library_url: ${{ matrix.traits.url }}
disable_default_traits: ${{ matrix.traits.disable_pico }}
- run: git add include/jwt-cpp/traits/*
- uses: ./.github/actions/process-linting-results
with:
linter_name: render-defaults
render-tests:
runs-on: ubuntu-20.04
strategy:
fail-fast: false
matrix:
traits:
# - { name: "boost_json", suite: "BoostJsonTest" } # Currently needs work arounds for API limitations
- { name: "danielaparker_jsoncons", suite: "JsonconsTest" }
# - { name: "kazuho_picojson", suite: "PicoJsonTest" } # Currently the default everything tests against this!
- { name: "nlohmann_json", suite: "NlohmannTest" }
name: render-tests (${{ matrix.traits.name }})
steps:
- uses: actions/checkout@v3
- run: shopt -s globstar
- uses: ./.github/actions/render/tests
with:
traits_name: ${{ matrix.traits.name }}
test_suite_name: ${{ matrix.traits.suite }}
- run: clang-format -i tests/**/*.cpp
- run: git add tests/traits/*
- uses: ./.github/actions/process-linting-results
with:
linter_name: render-tests
line-ending:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
- run: git add --renormalize .
- uses: ./.github/actions/process-linting-results
with:
linter_name: line-ending
-27
View File
@@ -1,27 +0,0 @@
name: Nuget CD
on:
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#release
release:
types: [published]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup NuGet
uses: NuGet/setup-nuget@v1
with:
nuget-api-key: ${{ secrets.nuget_api_key }}
- name: Create NuGet pkg
working-directory: ./nuget
run: nuget pack jwt-cpp.nuspec
- name: Publish NuGet pkg
working-directory: ./nuget
run: nuget push *.nupkg -Source 'https://api.nuget.org/v3/index.json'
-110
View File
@@ -1,110 +0,0 @@
name: SSL Compatibility CI
on:
push:
branches: [master]
pull_request:
branches: [master]
jobs:
openssl:
runs-on: ubuntu-latest
strategy:
matrix:
openssl:
- { tag: "openssl-3.0.5", name: "3.0.5" }
- { tag: "OpenSSL_1_1_1q", name: "1.1.1q" }
- { tag: "OpenSSL_1_1_0i", name: "1.1.0i" } # Do not bump, there's a broken in the autoconfig script and it's not maintained
- { tag: "OpenSSL_1_0_2u", name: "1.0.2u" }
- { tag: "OpenSSL_1_0_1u", name: "1.0.1u" }
name: OpenSSL ${{ matrix.openssl.name }}
steps:
- uses: actions/checkout@v3
- uses: lukka/get-cmake@latest
- uses: ./.github/actions/install/gtest
- uses: ./.github/actions/install/openssl
with:
version: ${{ matrix.openssl.tag }}
- name: configure
run: cmake . -DJWT_BUILD_TESTS=ON -DOPENSSL_ROOT_DIR=/tmp
- run: make
- name: test
run: ./tests/jwt-cpp-test
- if: github.event_name == 'push' && always()
uses: ./.github/actions/badge
with:
category: openssl
label: ${{ matrix.openssl.name }}
openssl-no-deprecated:
runs-on: ubuntu-latest
name: OpenSSL 3.0 No Deprecated
steps:
- uses: actions/checkout@v3
- uses: lukka/get-cmake@latest
- uses: ./.github/actions/install/gtest
- uses: ./.github/actions/install/openssl
with:
version: "openssl-3.0.5"
- name: configure
run: cmake . -DJWT_BUILD_TESTS=ON -DOPENSSL_ROOT_DIR=/tmp -DCMAKE_CXX_FLAGS="-DOPENSSL_NO_DEPRECATED=1" -DCMAKE_C_FLAGS="-DOPENSSL_NO_DEPRECATED=1"
- run: make
libressl:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
libressl: ["3.5.3", "3.4.3", "3.3.6"]
name: LibreSSL ${{ matrix.libressl }}
steps:
- uses: actions/checkout@v3
- uses: lukka/get-cmake@latest
- uses: ./.github/actions/install/gtest
- uses: ./.github/actions/install/libressl
with:
version: ${{ matrix.libressl }}
- name: configure
run: cmake . -DJWT_BUILD_TESTS=ON -DJWT_SSL_LIBRARY:STRING=LibreSSL
- run: make
- name: test
run: ./tests/jwt-cpp-test
- if: github.event_name == 'push' && always()
uses: ./.github/actions/badge
with:
category: libressl
label: ${{ matrix.libressl }}
wolfssl:
runs-on: ubuntu-latest
strategy:
matrix:
wolfssl:
- { ref: "v5.1.1-stable", name: "5.1.1"}
- { ref: "v5.2.0-stable", name: "5.2.0" }
- { ref: "v5.3.0-stable", name: "5.3.0"}
name: wolfSSL ${{ matrix.wolfssl.name }}
steps:
- uses: actions/checkout@v3
- uses: lukka/get-cmake@latest
- uses: ./.github/actions/install/gtest
- uses: ./.github/actions/install/wolfssl
with:
version: ${{ matrix.wolfssl.ref }}
- name: configure
run: cmake . -DJWT_BUILD_TESTS=ON -DJWT_SSL_LIBRARY:STRING=wolfSSL
- run: make
- name: test
run: ./tests/jwt-cpp-test
- if: github.event_name == 'push' && always()
uses: ./.github/actions/badge
with:
category: wolfssl
label: ${{ matrix.wolfssl.name }}
-75
View File
@@ -1,75 +0,0 @@
name: Specific Targets CI
on:
push:
branches: [master]
pull_request:
branches: [master]
paths:
- "CMakeLists.txt"
- "cmake/**"
- "include/jwt-cpp/**"
- "tests/cmake/**"
- ".github/actions/**"
- ".github/workflows/targets.yml"
jobs:
gcc-4-8:
name: GCC 4.8
runs-on: ubuntu-latest
container:
image: ubuntu:bionic-20230530 # 18.04
env:
CC: /usr/bin/gcc-4.8
CXX: /usr/bin/g++-4.8
steps:
- run: |
apt-get update
apt-get install -y g++-4.8 wget make libssl-dev
- uses: actions/checkout@v3
- uses: ./.github/actions/install/cmake
with:
version: "3.26.3"
url: "https://cmake.org/files/v3.26/cmake-3.26.3.tar.gz"
- name: setup
run: |
mkdir build
cd build
cmake ..
cmake --install .
- name: test
working-directory: tests/cmake
run: |
CC=gcc-4.8 CXX=g++-4.8 cmake . -DTEST:STRING="defaults-enabled"
cmake --build .
gcc-12:
runs-on: ubuntu-latest
container:
image: ubuntu:jammy-20231004 # 22.04
env:
CC: /usr/bin/gcc-12
CXX: /usr/bin/g++-12
steps:
- run: |
apt-get update
apt-get install -y g++-12 wget make libssl-dev
- uses: actions/checkout@v3
- uses: ./.github/actions/install/cmake
with:
version: "3.26.3"
url: "https://cmake.org/files/v3.26/cmake-3.26.3.tar.gz"
- name: setup
run: |
mkdir build
cd build
cmake ..
cmake --install .
- name: test
working-directory: tests/cmake
run: |
CC=gcc-12 CXX=g++-12 cmake . -DCMAKE_CXX_STANDARD=20 -DTEST:STRING="defaults-enabled"
cmake --build .
-79
View File
@@ -1,79 +0,0 @@
name: Traits CI
on:
push:
branches: [master]
pull_request:
branches: [master]
jobs:
traits:
name: Traits (${{ matrix.target.name }})
runs-on: ubuntu-latest
strategy:
matrix:
target:
- { name: "danielaparker-jsoncons", tag: "0.168.7", version: "v0.168.7" }
- { name: "boost-json", tag: "1.78.0", version: "v1.80.0" }
- { name: "nlohmann-json", tag: "3.11.2", version: "v3.11.2" }
- { name: "kazuho-picojson", tag: "111c9be5188f7350c2eac9ddaedd8cca3d7bf394", version: "111c9be" }
steps:
- uses: actions/checkout@v3
- uses: lukka/get-cmake@latest
- name: setup
run: |
mkdir build
cd build
cmake .. -DJWT_BUILD_EXAMPLES=OFF
sudo cmake --install .
# Install the JSON library
- if: matrix.target.name == 'danielaparker-jsoncons'
uses: ./.github/actions/install/danielaparker-jsoncons
with:
version: ${{matrix.target.tag}}
- if: matrix.target.name == 'boost-json'
uses: ./.github/actions/install/boost-json
with:
version: ${{matrix.target.tag}}
- if: matrix.target.name == 'nlohmann-json'
uses: ./.github/actions/install/nlohmann-json
with:
version: ${{matrix.target.tag}}
- if: matrix.target.name == 'kazuho-picojson'
run: rm -rf include/picojson
- if: matrix.target.name == 'kazuho-picojson'
uses: ./.github/actions/install/kazuho-picojson
with:
version: ${{matrix.target.tag}}
- name: test
working-directory: example/traits
run: |
cmake . -DCMAKE_FIND_DEBUG_MODE=1
cmake --build . --target ${{ matrix.target.name }}
./${{ matrix.target.name }}
- name: badge success
if: github.event_name == 'push' && success()
uses: ./.github/actions/badge/write
with:
category: traits
label: ${{ matrix.target.name }}
message: ${{ matrix.target.version }}
color: lightblue # turquoise
- name: badge failure
if: github.event_name == 'push' && !success()
uses: ./.github/actions/badge/write
with:
category: traits
label: ${{ matrix.target.name }}
message: ${{ matrix.target.version }}
color: orange
- if: github.event_name == 'push' && always()
uses: ./.github/actions/badge/publish
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
-317
View File
@@ -1,317 +0,0 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# DNX
project.lock.json
artifacts/
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignoreable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.pfx
*.publishsettings
node_modules/
orleans.codegen.cs
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# =========================
# Operating System Files
# =========================
# OSX
# =========================
.DS_Store
.AppleDouble
.LSOverride
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
# Windows
# =========================
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msm
*.msp
# Windows shortcuts
*.lnk
# Linux files
test
*.o
*.o.d
.vscode
# ClangD cache files
.cache
doxy/
doxygen-awesome*.css
build/*
package-lock.json
-157
View File
@@ -1,157 +0,0 @@
cmake_minimum_required(VERSION 3.14)
cmake_policy(VERSION 3.14)
if(POLICY CMP0135) # DOWNLOAD_EXTRACT_TIMESTAMP
cmake_policy(SET CMP0135 OLD)
endif()
# HUNTER_ENABLED is always set if this package is included in a project using hunter (HunterGate sets it) In this case
# we will use hunter as well to stay consistent. If not the use can supply it on configure to force using hunter.
if(HUNTER_ENABLED)
include("cmake/HunterGate.cmake")
huntergate(URL "https://github.com/cpp-pm/hunter/archive/v0.23.314.tar.gz" SHA1
"95c47c92f68edb091b5d6d18924baabe02a6962a")
message(STATUS "jwt-cpp: using hunter for dependency resolution")
endif()
project(jwt-cpp)
option(JWT_BUILD_EXAMPLES "Configure CMake to build examples (or not)" ON)
option(JWT_BUILD_TESTS "Configure CMake to build tests (or not)" OFF)
option(JWT_ENABLE_COVERAGE "Enable code coverage testing" OFF)
option(JWT_ENABLE_FUZZING "Enable fuzz testing" OFF)
option(JWT_EXTERNAL_PICOJSON "Use find_package() to locate picojson, provided to integrate with package managers" OFF)
option(JWT_DISABLE_BASE64 "Do not include the base64 implementation from this library" OFF)
option(JWT_DISABLE_PICOJSON "Do not provide the picojson template specialiaze" OFF)
set(JWT_SSL_LIBRARY_OPTIONS OpenSSL LibreSSL wolfSSL)
set(JWT_SSL_LIBRARY OpenSSL CACHE STRING "Determines which SSL library to build with")
set_property(CACHE JWT_SSL_LIBRARY PROPERTY STRINGS ${JWT_SSL_LIBRARY_OPTIONS})
set(JWT_JSON_TRAITS_OPTIONS boost-json danielaparker-jsoncons kazuho-picojson nlohmann-json)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
if(NOT JWT_SSL_LIBRARY IN_LIST JWT_SSL_LIBRARY_OPTIONS)
message(FATAL_ERROR "JWT_SSL_LIBRARY must be one of ${JWT_SSL_LIBRARY_OPTIONS}")
endif()
# If Hunter is enabled, we configure it to resolve OpenSSL and warn the user if he selected an option not supported by
# hunter. We fall back to the system library in this case.
if(HUNTER_ENABLED)
if(${JWT_SSL_LIBRARY} MATCHES "OpenSSL")
hunter_add_package(OpenSSL)
elseif(${JWT_SSL_LIBRARY} MATCHES "LibreSSL")
message(WARNING "Hunter does not support LibreSSL yet, the system library will be used (if available)")
elseif(${JWT_SSL_LIBRARY} MATCHES "wolfSSL")
message(WARNING "Hunter does not support wolfSSL yet, the system library will be used (if available)")
endif()
if(JWT_EXTERNAL_PICOJSON)
message(WARNING "Hunter does not support picojson yet, the system library will be used (if available)")
endif()
endif()
# Lookup dependencies
if(${JWT_SSL_LIBRARY} MATCHES "OpenSSL")
find_package(OpenSSL 1.0.1 REQUIRED)
elseif(${JWT_SSL_LIBRARY} MATCHES "LibreSSL")
find_package(LibreSSL 3.0.0 REQUIRED)
elseif(${JWT_SSL_LIBRARY} MATCHES "wolfSSL")
find_package(PkgConfig REQUIRED)
pkg_check_modules(wolfssl REQUIRED IMPORTED_TARGET wolfssl)
list(TRANSFORM wolfssl_INCLUDE_DIRS APPEND "/wolfssl") # This is required to access OpenSSL compatibility API
endif()
if(JWT_EXTERNAL_PICOJSON)
find_package(picojson 1.3.0 REQUIRED)
endif()
find_package(nlohmann_json CONFIG)
if(NOT nlohmann_json_FOUND)
message(STATUS "jwt-cpp: using FetchContent for nlohmann json")
include(FetchContent)
FetchContent_Declare(nlohmann_json
URL https://github.com/nlohmann/json/releases/download/v3.11.2/json.tar.xz
URL_MD5 127794b2c82c0c5693805feaa2a703e2
)
FetchContent_MakeAvailable(nlohmann_json)
endif()
set(JWT_INCLUDE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/include)
set(JWT_HEADER_FILES ${JWT_INCLUDE_PATH}/jwt-cpp/jwt.h)
foreach(traits ${JWT_JSON_TRAITS_OPTIONS})
list(APPEND JWT_HEADER_FILES ${JWT_INCLUDE_PATH}/jwt-cpp/traits/${traits}/defaults.h
${JWT_INCLUDE_PATH}/jwt-cpp/traits/${traits}/traits.h)
endforeach()
if(NOT JWT_DISABLE_BASE64)
list(APPEND JWT_HEADER_FILES ${JWT_INCLUDE_PATH}/jwt-cpp/base.h)
endif()
add_library(jwt-cpp INTERFACE)
add_library(jwt-cpp::jwt-cpp ALIAS jwt-cpp) # To match export
target_compile_features(jwt-cpp INTERFACE cxx_std_11)
if(JWT_DISABLE_BASE64)
target_compile_definitions(jwt-cpp INTERFACE JWT_DISABLE_BASE64)
endif()
if(JWT_DISABLE_PICOJSON)
target_compile_definitions(jwt-cpp INTERFACE JWT_DISABLE_PICOJSON)
endif()
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
target_include_directories(jwt-cpp INTERFACE $<BUILD_INTERFACE:${JWT_INCLUDE_PATH}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
if(${JWT_SSL_LIBRARY} MATCHES "OpenSSL")
target_link_libraries(jwt-cpp INTERFACE OpenSSL::SSL OpenSSL::Crypto)
endif()
if(${JWT_SSL_LIBRARY} MATCHES "LibreSSL")
target_link_libraries(jwt-cpp INTERFACE LibreSSL::TLS)
endif()
if(${JWT_SSL_LIBRARY} MATCHES "wolfSSL")
target_link_libraries(jwt-cpp INTERFACE PkgConfig::wolfssl)
# This is required to access OpenSSL compatibility API
target_include_directories(jwt-cpp INTERFACE ${wolfssl_INCLUDE_DIRS})
target_compile_definitions(jwt-cpp INTERFACE OPENSSL_EXTRA OPENSSL_ALL)
endif()
if(JWT_EXTERNAL_PICOJSON)
target_link_libraries(jwt-cpp INTERFACE picojson::picojson>)
endif()
# Hunter needs relative paths so the files are placed correctly
if(NOT JWT_CMAKE_FILES_INSTALL_DIR)
set(JWT_CMAKE_FILES_INSTALL_DIR cmake)
endif()
configure_package_config_file(
${CMAKE_CURRENT_LIST_DIR}/cmake/jwt-cpp-config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/jwt-cpp-config.cmake
INSTALL_DESTINATION ${JWT_CMAKE_FILES_INSTALL_DIR} PATH_VARS JWT_EXTERNAL_PICOJSON JWT_SSL_LIBRARY)
write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/jwt-cpp-config-version.cmake VERSION 0.7.0
COMPATIBILITY ExactVersion)
install(TARGETS jwt-cpp EXPORT jwt-cpp-targets PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install(EXPORT jwt-cpp-targets NAMESPACE jwt-cpp:: FILE jwt-cpp-targets.cmake
DESTINATION ${JWT_CMAKE_FILES_INSTALL_DIR})
install(DIRECTORY ${JWT_INCLUDE_PATH}/jwt-cpp DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
if(NOT JWT_EXTERNAL_PICOJSON AND NOT JWT_DISABLE_PICOJSON)
install(FILES ${JWT_INCLUDE_PATH}/picojson/picojson.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/picojson)
endif()
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/jwt-cpp-config.cmake ${CMAKE_CURRENT_BINARY_DIR}/jwt-cpp-config-version.cmake
DESTINATION ${JWT_CMAKE_FILES_INSTALL_DIR})
if(JWT_BUILD_EXAMPLES)
add_subdirectory(example)
endif()
if(JWT_BUILD_TESTS)
add_subdirectory(tests)
endif()
if(JWT_ENABLE_FUZZING)
add_subdirectory(tests/fuzz)
endif()
File diff suppressed because it is too large Load Diff
-21
View File
@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2018 Dominik Thalhammer
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
-155
View File
@@ -1,155 +0,0 @@
<img src="https://raw.githubusercontent.com/Thalhammer/jwt-cpp/master/.github/logo.svg" alt="logo" width="100%">
[![License Badge](https://img.shields.io/github/license/Thalhammer/jwt-cpp)](https://github.com/Thalhammer/jwt-cpp/blob/master/LICENSE)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/5f7055e294744901991fd0a1620b231d)](https://app.codacy.com/gh/Thalhammer/jwt-cpp/dashboard)
[![Linux Badge][Linux]][Cross-Platform]
[![MacOS Badge][MacOS]][Cross-Platform]
[![Windows Badge][Windows]][Cross-Platform]
[![Coverage Status](https://coveralls.io/repos/github/Thalhammer/jwt-cpp/badge.svg?branch=master)](https://coveralls.io/github/Thalhammer/jwt-cpp?branch=master)
[![Documentation Badge](https://img.shields.io/badge/Documentation-master-blue)](https://thalhammer.github.io/jwt-cpp/)
[![Stars Badge](https://img.shields.io/github/stars/Thalhammer/jwt-cpp)](https://github.com/Thalhammer/jwt-cpp/stargazers)
[![GitHub release (latest SemVer including pre-releases)](https://img.shields.io/github/v/release/Thalhammer/jwt-cpp?include_prereleases)](https://github.com/Thalhammer/jwt-cpp/releases)
[![ConanCenter package](https://repology.org/badge/version-for-repo/conancenter/jwt-cpp.svg)](https://repology.org/project/jwt-cpp/versions)
[![Vcpkg package](https://repology.org/badge/version-for-repo/vcpkg/jwt-cpp.svg)](https://repology.org/project/jwt-cpp/versions)
[Linux]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/Thalhammer/jwt-cpp/badges/cross-platform/ubuntu-latest/shields.json
[MacOS]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/Thalhammer/jwt-cpp/badges/cross-platform/macos-latest/shields.json
[Windows]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/Thalhammer/jwt-cpp/badges/cross-platform/windows-latest/shields.json
[Cross-Platform]: https://github.com/Thalhammer/jwt-cpp/actions?query=workflow%3A%22Cross-Platform+CI%22
A header only library for creating and validating [JSON Web Tokens](https://tools.ietf.org/html/rfc7519) in C++11. For a great introduction, [read this](https://jwt.io/introduction/).
## Signature algorithms
jwt-cpp supports all the algorithms defined by the specifications. The modular design allows to easily add additional algorithms without any problems. If you need any feel free to create a pull request or [open an issue](https://github.com/Thalhammer/jwt-cpp/issues/new).
For completeness, here is a list of all supported algorithms:
| HMSC | RSA | ECDSA | PSS | EdDSA |
|-------|-------|--------|-------|---------|
| HS256 | RS256 | ES256 | PS256 | Ed25519 |
| HS384 | RS384 | ES384 | PS384 | Ed448 |
| HS512 | RS512 | ES512 | PS512 | |
| | | ES256K | | |
## SSL Compatibility
In the name of flexibility and extensibility, jwt-cpp supports [OpenSSL](https://github.com/openssl/openssl), [LibreSSL](https://github.com/libressl-portable/portable), and [wolfSSL](https://github.com/wolfSSL/wolfssl). Read [this page](docs/ssl.md) for more details. These are the version which are currently being tested:
| OpenSSL | LibreSSL | wolfSSL |
|-------------------|----------------|----------------|
| ![1.0.2u][o1.0.2] | ![3.3.6][l3.3] | ![5.1.1][w5.1] |
| ![1.1.0i][o1.1.0] | ![3.4.3][l3.4] | ![5.2.0][w5.2] |
| ![1.1.1q][o1.1.1] | ![3.5.3][l3.5] | ![5.3.0][w5.3] |
| ![3.0.5][o3.0] | | |
> ℹ️ Note: A complete list of versions tested in the past can be found [here](https://github.com/Thalhammer/jwt-cpp/tree/badges).
[o1.0.2]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/Thalhammer/jwt-cpp/badges/openssl/1.0.2u/shields.json
[o1.1.0]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/Thalhammer/jwt-cpp/badges/openssl/1.1.0i/shields.json
[o1.1.1]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/Thalhammer/jwt-cpp/badges/openssl/1.1.1q/shields.json
[o3.0]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/Thalhammer/jwt-cpp/badges/openssl/3.0.5/shields.json
[l3.3]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/Thalhammer/jwt-cpp/badges/libressl/3.3.6/shields.json
[l3.4]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/Thalhammer/jwt-cpp/badges/libressl/3.4.3/shields.json
[l3.5]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/Thalhammer/jwt-cpp/badges/libressl/3.5.3/shields.json
[w5.1]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/Thalhammer/jwt-cpp/badges/wolfssl/5.1.1/shields.json
[w5.2]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/Thalhammer/jwt-cpp/badges/wolfssl/5.2.0/shields.json
[w5.3]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/Thalhammer/jwt-cpp/badges/wolfssl/5.3.0/shields.json
## Overview
There is no hard dependency on a JSON library. Instead, there's a generic `jwt::basic_claim` which is templated around type traits, which described the semantic [JSON types](https://json-schema.org/understanding-json-schema/reference/type.html) for a value, object, array, string, number, integer and boolean, as well as methods to translate between them.
```cpp
jwt::basic_claim<my_favorite_json_library_traits> claim(json::object({{"json", true},{"example", 0}}));
```
This allows for complete freedom when picking which libraries you want to use. For more information, [read this page](docs/traits.md)).
For your convenience there are serval traits implementation which provide some popular JSON libraries. They are:
[![picojson][picojson]](https://github.com/kazuho/picojson)
[![nlohmann][nlohmann]](https://github.com/nlohmann/json)
[![jsoncons][jsoncons]](https://github.com/danielaparker/jsoncons)
[![boostjson][boostjson]](https://github.com/boostorg/json)
[picojson]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/Thalhammer/jwt-cpp/badges/traits/kazuho-picojson/shields.json
[nlohmann]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/Thalhammer/jwt-cpp/badges/traits/nlohmann-json/shields.json
[jsoncons]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/Thalhammer/jwt-cpp/badges/traits/danielaparker-jsoncons/shields.json
[boostjson]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/Thalhammer/jwt-cpp/badges/traits/boost-json/shields.json
In order to maintain compatibility, [picojson](https://github.com/kazuho/picojson) is still used to provide a specialized `jwt::claim` along with all helpers. Defining `JWT_DISABLE_PICOJSON` will remove this optional dependency. It's possible to directly include the traits defaults for the other JSON libraries. See the [traits examples](https://github.com/Thalhammer/jwt-cpp/tree/master/example/traits) for details.
As for the base64 requirements of JWTs, this library provides `base.h` with all the required implementation; However base64 implementations are very common, with varying degrees of performance. When providing your own base64 implementation, you can define `JWT_DISABLE_BASE64` to remove the jwt-cpp implementation.
### Getting Started
Simple example of decoding a token and printing all [claims](https://tools.ietf.org/html/rfc7519#section-4) ([try it out](https://github.com/Thalhammer/jwt-cpp/tree/master/example/print-claims.cpp)):
```cpp
#include <jwt-cpp/jwt.h>
#include <iostream>
int main() {
std::string token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCJ9.AbIJTDMFc7yUa5MhvcP03nJPyCPzZtQcGEp-zWfOkEE";
auto decoded = jwt::decode(token);
for(auto& e : decoded.get_payload_json())
std::cout << e.first << " = " << e.second << std::endl;
}
```
In order to verify a token you first build a verifier and use it to verify a decoded token.
```cpp
auto verifier = jwt::verify()
.allow_algorithm(jwt::algorithm::hs256{ "secret" })
.with_issuer("auth0");
verifier.verify(decoded_token);
```
The created verifier is stateless so you can reuse it for different tokens.
Creating a token (and signing) is equally as easy.
```cpp
auto token = jwt::create()
.set_issuer("auth0")
.set_type("JWS")
.set_payload_claim("sample", jwt::claim(std::string("test")))
.sign(jwt::algorithm::hs256{"secret"});
```
> To see more examples working with RSA public and private keys, visit our [examples](https://github.com/Thalhammer/jwt-cpp/tree/master/example)!
### Providing your own JSON Traits
To learn how to writes a trait's implementation, checkout the [these instructions](docs/traits.md)
## Contributing
If you have an improvement or found a bug feel free to [open an issue](https://github.com/Thalhammer/jwt-cpp/issues/new) or add the change and create a pull request. If you file a bug please make sure to include as much information about your environment (compiler version, etc.) as possible to help reproduce the issue. If you add a new feature please make sure to also include test cases for it.
## Dependencies
In order to use jwt-cpp you need the following tools.
* libcrypto (openssl or compatible)
* libssl-dev (for the header files)
* a compiler supporting at least c++11
* basic stl support
In order to build the test cases you also need
* gtest
* pthread
## Troubleshooting
See the [FAQs](docs/faqs.md) for tips.
## Conference Coverage
[![CppCon](https://img.youtube.com/vi/Oq4NW5idmiI/0.jpg)](https://www.youtube.com/watch?v=Oq4NW5idmiI)
@@ -1,537 +0,0 @@
# Copyright (c) 2013-2019, Ruslan Baratov
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# This is a gate file to Hunter package manager.
# Include this file using `include` command and add package you need, example:
#
# cmake_minimum_required(VERSION 3.2)
#
# include("cmake/HunterGate.cmake")
# HunterGate(
# URL "https://github.com/path/to/hunter/archive.tar.gz"
# SHA1 "798501e983f14b28b10cda16afa4de69eee1da1d"
# )
#
# project(MyProject)
#
# hunter_add_package(Foo)
# hunter_add_package(Boo COMPONENTS Bar Baz)
#
# Projects:
# * https://github.com/hunter-packages/gate/
# * https://github.com/ruslo/hunter
option(HUNTER_ENABLED "Enable Hunter package manager support" ON)
if(HUNTER_ENABLED)
if(CMAKE_VERSION VERSION_LESS "3.2")
message(
FATAL_ERROR
"At least CMake version 3.2 required for Hunter dependency management."
" Update CMake or set HUNTER_ENABLED to OFF."
)
endif()
endif()
include(CMakeParseArguments) # cmake_parse_arguments
option(HUNTER_STATUS_PRINT "Print working status" ON)
option(HUNTER_STATUS_DEBUG "Print a lot info" OFF)
option(HUNTER_TLS_VERIFY "Enable/disable TLS certificate checking on downloads" ON)
set(HUNTER_ROOT "" CACHE FILEPATH "Override the HUNTER_ROOT.")
set(HUNTER_ERROR_PAGE "https://hunter.readthedocs.io/en/latest/reference/errors")
function(hunter_gate_status_print)
if(HUNTER_STATUS_PRINT OR HUNTER_STATUS_DEBUG)
foreach(print_message ${ARGV})
message(STATUS "[hunter] ${print_message}")
endforeach()
endif()
endfunction()
function(hunter_gate_status_debug)
if(HUNTER_STATUS_DEBUG)
foreach(print_message ${ARGV})
string(TIMESTAMP timestamp)
message(STATUS "[hunter *** DEBUG *** ${timestamp}] ${print_message}")
endforeach()
endif()
endfunction()
function(hunter_gate_error_page error_page)
message("------------------------------ ERROR ------------------------------")
message(" ${HUNTER_ERROR_PAGE}/${error_page}.html")
message("-------------------------------------------------------------------")
message("")
message(FATAL_ERROR "")
endfunction()
function(hunter_gate_internal_error)
message("")
foreach(print_message ${ARGV})
message("[hunter ** INTERNAL **] ${print_message}")
endforeach()
message("[hunter ** INTERNAL **] [Directory:${CMAKE_CURRENT_LIST_DIR}]")
message("")
hunter_gate_error_page("error.internal")
endfunction()
function(hunter_gate_fatal_error)
cmake_parse_arguments(hunter "" "ERROR_PAGE" "" "${ARGV}")
if("${hunter_ERROR_PAGE}" STREQUAL "")
hunter_gate_internal_error("Expected ERROR_PAGE")
endif()
message("")
foreach(x ${hunter_UNPARSED_ARGUMENTS})
message("[hunter ** FATAL ERROR **] ${x}")
endforeach()
message("[hunter ** FATAL ERROR **] [Directory:${CMAKE_CURRENT_LIST_DIR}]")
message("")
hunter_gate_error_page("${hunter_ERROR_PAGE}")
endfunction()
function(hunter_gate_user_error)
hunter_gate_fatal_error(${ARGV} ERROR_PAGE "error.incorrect.input.data")
endfunction()
function(hunter_gate_self root version sha1 result)
string(COMPARE EQUAL "${root}" "" is_bad)
if(is_bad)
hunter_gate_internal_error("root is empty")
endif()
string(COMPARE EQUAL "${version}" "" is_bad)
if(is_bad)
hunter_gate_internal_error("version is empty")
endif()
string(COMPARE EQUAL "${sha1}" "" is_bad)
if(is_bad)
hunter_gate_internal_error("sha1 is empty")
endif()
string(SUBSTRING "${sha1}" 0 7 archive_id)
if(EXISTS "${root}/cmake/Hunter")
set(hunter_self "${root}")
else()
set(
hunter_self
"${root}/_Base/Download/Hunter/${version}/${archive_id}/Unpacked"
)
endif()
set("${result}" "${hunter_self}" PARENT_SCOPE)
endfunction()
# Set HUNTER_GATE_ROOT cmake variable to suitable value.
function(hunter_gate_detect_root)
# Check CMake variable
if(HUNTER_ROOT)
set(HUNTER_GATE_ROOT "${HUNTER_ROOT}" PARENT_SCOPE)
hunter_gate_status_debug("HUNTER_ROOT detected by cmake variable")
return()
endif()
# Check environment variable
if(DEFINED ENV{HUNTER_ROOT})
set(HUNTER_GATE_ROOT "$ENV{HUNTER_ROOT}" PARENT_SCOPE)
hunter_gate_status_debug("HUNTER_ROOT detected by environment variable")
return()
endif()
# Check HOME environment variable
if(DEFINED ENV{HOME})
set(HUNTER_GATE_ROOT "$ENV{HOME}/.hunter" PARENT_SCOPE)
hunter_gate_status_debug("HUNTER_ROOT set using HOME environment variable")
return()
endif()
# Check SYSTEMDRIVE and USERPROFILE environment variable (windows only)
if(WIN32)
if(DEFINED ENV{SYSTEMDRIVE})
set(HUNTER_GATE_ROOT "$ENV{SYSTEMDRIVE}/.hunter" PARENT_SCOPE)
hunter_gate_status_debug(
"HUNTER_ROOT set using SYSTEMDRIVE environment variable"
)
return()
endif()
if(DEFINED ENV{USERPROFILE})
set(HUNTER_GATE_ROOT "$ENV{USERPROFILE}/.hunter" PARENT_SCOPE)
hunter_gate_status_debug(
"HUNTER_ROOT set using USERPROFILE environment variable"
)
return()
endif()
endif()
hunter_gate_fatal_error(
"Can't detect HUNTER_ROOT"
ERROR_PAGE "error.detect.hunter.root"
)
endfunction()
function(hunter_gate_download dir)
string(
COMPARE
NOTEQUAL
"$ENV{HUNTER_DISABLE_AUTOINSTALL}"
""
disable_autoinstall
)
if(disable_autoinstall AND NOT HUNTER_RUN_INSTALL)
hunter_gate_fatal_error(
"Hunter not found in '${dir}'"
"Set HUNTER_RUN_INSTALL=ON to auto-install it from '${HUNTER_GATE_URL}'"
"Settings:"
" HUNTER_ROOT: ${HUNTER_GATE_ROOT}"
" HUNTER_SHA1: ${HUNTER_GATE_SHA1}"
ERROR_PAGE "error.run.install"
)
endif()
string(COMPARE EQUAL "${dir}" "" is_bad)
if(is_bad)
hunter_gate_internal_error("Empty 'dir' argument")
endif()
string(COMPARE EQUAL "${HUNTER_GATE_SHA1}" "" is_bad)
if(is_bad)
hunter_gate_internal_error("HUNTER_GATE_SHA1 empty")
endif()
string(COMPARE EQUAL "${HUNTER_GATE_URL}" "" is_bad)
if(is_bad)
hunter_gate_internal_error("HUNTER_GATE_URL empty")
endif()
set(done_location "${dir}/DONE")
set(sha1_location "${dir}/SHA1")
set(build_dir "${dir}/Build")
set(cmakelists "${dir}/CMakeLists.txt")
hunter_gate_status_debug("Locking directory: ${dir}")
file(LOCK "${dir}" DIRECTORY GUARD FUNCTION)
hunter_gate_status_debug("Lock done")
if(EXISTS "${done_location}")
# while waiting for lock other instance can do all the job
hunter_gate_status_debug("File '${done_location}' found, skip install")
return()
endif()
file(REMOVE_RECURSE "${build_dir}")
file(REMOVE_RECURSE "${cmakelists}")
file(MAKE_DIRECTORY "${build_dir}") # check directory permissions
# Disabling languages speeds up a little bit, reduces noise in the output
# and avoids path too long windows error
file(
WRITE
"${cmakelists}"
"cmake_minimum_required(VERSION 3.2)\n"
"project(HunterDownload LANGUAGES NONE)\n"
"include(ExternalProject)\n"
"ExternalProject_Add(\n"
" Hunter\n"
" URL\n"
" \"${HUNTER_GATE_URL}\"\n"
" URL_HASH\n"
" SHA1=${HUNTER_GATE_SHA1}\n"
" DOWNLOAD_DIR\n"
" \"${dir}\"\n"
" TLS_VERIFY\n"
" ${HUNTER_TLS_VERIFY}\n"
" SOURCE_DIR\n"
" \"${dir}/Unpacked\"\n"
" CONFIGURE_COMMAND\n"
" \"\"\n"
" BUILD_COMMAND\n"
" \"\"\n"
" INSTALL_COMMAND\n"
" \"\"\n"
")\n"
)
if(HUNTER_STATUS_DEBUG)
set(logging_params "")
else()
set(logging_params OUTPUT_QUIET)
endif()
hunter_gate_status_debug("Run generate")
# Need to add toolchain file too.
# Otherwise on Visual Studio + MDD this will fail with error:
# "Could not find an appropriate version of the Windows 10 SDK installed on this machine"
if(EXISTS "${CMAKE_TOOLCHAIN_FILE}")
get_filename_component(absolute_CMAKE_TOOLCHAIN_FILE "${CMAKE_TOOLCHAIN_FILE}" ABSOLUTE)
set(toolchain_arg "-DCMAKE_TOOLCHAIN_FILE=${absolute_CMAKE_TOOLCHAIN_FILE}")
else()
# 'toolchain_arg' can't be empty
set(toolchain_arg "-DCMAKE_TOOLCHAIN_FILE=")
endif()
string(COMPARE EQUAL "${CMAKE_MAKE_PROGRAM}" "" no_make)
if(no_make)
set(make_arg "")
else()
# Test case: remove Ninja from PATH but set it via CMAKE_MAKE_PROGRAM
set(make_arg "-DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM}")
endif()
execute_process(
COMMAND
"${CMAKE_COMMAND}"
"-H${dir}"
"-B${build_dir}"
"-G${CMAKE_GENERATOR}"
"${toolchain_arg}"
${make_arg}
WORKING_DIRECTORY "${dir}"
RESULT_VARIABLE download_result
${logging_params}
)
if(NOT download_result EQUAL 0)
hunter_gate_internal_error(
"Configure project failed."
"To reproduce the error run: ${CMAKE_COMMAND} -H${dir} -B${build_dir} -G${CMAKE_GENERATOR} ${toolchain_arg} ${make_arg}"
"In directory ${dir}"
)
endif()
hunter_gate_status_print(
"Initializing Hunter workspace (${HUNTER_GATE_SHA1})"
" ${HUNTER_GATE_URL}"
" -> ${dir}"
)
execute_process(
COMMAND "${CMAKE_COMMAND}" --build "${build_dir}"
WORKING_DIRECTORY "${dir}"
RESULT_VARIABLE download_result
${logging_params}
)
if(NOT download_result EQUAL 0)
hunter_gate_internal_error("Build project failed")
endif()
file(REMOVE_RECURSE "${build_dir}")
file(REMOVE_RECURSE "${cmakelists}")
file(WRITE "${sha1_location}" "${HUNTER_GATE_SHA1}")
file(WRITE "${done_location}" "DONE")
hunter_gate_status_debug("Finished")
endfunction()
# Must be a macro so master file 'cmake/Hunter' can
# apply all variables easily just by 'include' command
# (otherwise PARENT_SCOPE magic needed)
macro(HunterGate)
if(HUNTER_GATE_DONE)
# variable HUNTER_GATE_DONE set explicitly for external project
# (see `hunter_download`)
set_property(GLOBAL PROPERTY HUNTER_GATE_DONE YES)
endif()
# First HunterGate command will init Hunter, others will be ignored
get_property(_hunter_gate_done GLOBAL PROPERTY HUNTER_GATE_DONE SET)
if(NOT HUNTER_ENABLED)
# Empty function to avoid error "unknown function"
function(hunter_add_package)
endfunction()
set(
_hunter_gate_disabled_mode_dir
"${CMAKE_CURRENT_LIST_DIR}/cmake/Hunter/disabled-mode"
)
if(EXISTS "${_hunter_gate_disabled_mode_dir}")
hunter_gate_status_debug(
"Adding \"disabled-mode\" modules: ${_hunter_gate_disabled_mode_dir}"
)
list(APPEND CMAKE_PREFIX_PATH "${_hunter_gate_disabled_mode_dir}")
endif()
elseif(_hunter_gate_done)
hunter_gate_status_debug("Secondary HunterGate (use old settings)")
hunter_gate_self(
"${HUNTER_CACHED_ROOT}"
"${HUNTER_VERSION}"
"${HUNTER_SHA1}"
_hunter_self
)
include("${_hunter_self}/cmake/Hunter")
else()
set(HUNTER_GATE_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}")
string(COMPARE NOTEQUAL "${PROJECT_NAME}" "" _have_project_name)
if(_have_project_name)
hunter_gate_fatal_error(
"Please set HunterGate *before* 'project' command. "
"Detected project: ${PROJECT_NAME}"
ERROR_PAGE "error.huntergate.before.project"
)
endif()
cmake_parse_arguments(
HUNTER_GATE "LOCAL" "URL;SHA1;GLOBAL;FILEPATH" "" ${ARGV}
)
string(COMPARE EQUAL "${HUNTER_GATE_SHA1}" "" _empty_sha1)
string(COMPARE EQUAL "${HUNTER_GATE_URL}" "" _empty_url)
string(
COMPARE
NOTEQUAL
"${HUNTER_GATE_UNPARSED_ARGUMENTS}"
""
_have_unparsed
)
string(COMPARE NOTEQUAL "${HUNTER_GATE_GLOBAL}" "" _have_global)
string(COMPARE NOTEQUAL "${HUNTER_GATE_FILEPATH}" "" _have_filepath)
if(_have_unparsed)
hunter_gate_user_error(
"HunterGate unparsed arguments: ${HUNTER_GATE_UNPARSED_ARGUMENTS}"
)
endif()
if(_empty_sha1)
hunter_gate_user_error("SHA1 suboption of HunterGate is mandatory")
endif()
if(_empty_url)
hunter_gate_user_error("URL suboption of HunterGate is mandatory")
endif()
if(_have_global)
if(HUNTER_GATE_LOCAL)
hunter_gate_user_error("Unexpected LOCAL (already has GLOBAL)")
endif()
if(_have_filepath)
hunter_gate_user_error("Unexpected FILEPATH (already has GLOBAL)")
endif()
endif()
if(HUNTER_GATE_LOCAL)
if(_have_global)
hunter_gate_user_error("Unexpected GLOBAL (already has LOCAL)")
endif()
if(_have_filepath)
hunter_gate_user_error("Unexpected FILEPATH (already has LOCAL)")
endif()
endif()
if(_have_filepath)
if(_have_global)
hunter_gate_user_error("Unexpected GLOBAL (already has FILEPATH)")
endif()
if(HUNTER_GATE_LOCAL)
hunter_gate_user_error("Unexpected LOCAL (already has FILEPATH)")
endif()
endif()
hunter_gate_detect_root() # set HUNTER_GATE_ROOT
# Beautify path, fix probable problems with windows path slashes
get_filename_component(
HUNTER_GATE_ROOT "${HUNTER_GATE_ROOT}" ABSOLUTE
)
hunter_gate_status_debug("HUNTER_ROOT: ${HUNTER_GATE_ROOT}")
if(NOT HUNTER_ALLOW_SPACES_IN_PATH)
string(FIND "${HUNTER_GATE_ROOT}" " " _contain_spaces)
if(NOT _contain_spaces EQUAL -1)
hunter_gate_fatal_error(
"HUNTER_ROOT (${HUNTER_GATE_ROOT}) contains spaces."
"Set HUNTER_ALLOW_SPACES_IN_PATH=ON to skip this error"
"(Use at your own risk!)"
ERROR_PAGE "error.spaces.in.hunter.root"
)
endif()
endif()
string(
REGEX
MATCH
"[0-9]+\\.[0-9]+\\.[0-9]+[-_a-z0-9]*"
HUNTER_GATE_VERSION
"${HUNTER_GATE_URL}"
)
string(COMPARE EQUAL "${HUNTER_GATE_VERSION}" "" _is_empty)
if(_is_empty)
set(HUNTER_GATE_VERSION "unknown")
endif()
hunter_gate_self(
"${HUNTER_GATE_ROOT}"
"${HUNTER_GATE_VERSION}"
"${HUNTER_GATE_SHA1}"
_hunter_self
)
set(_master_location "${_hunter_self}/cmake/Hunter")
if(EXISTS "${HUNTER_GATE_ROOT}/cmake/Hunter")
# Hunter downloaded manually (e.g. by 'git clone')
set(_unused "xxxxxxxxxx")
set(HUNTER_GATE_SHA1 "${_unused}")
set(HUNTER_GATE_VERSION "${_unused}")
else()
get_filename_component(_archive_id_location "${_hunter_self}/.." ABSOLUTE)
set(_done_location "${_archive_id_location}/DONE")
set(_sha1_location "${_archive_id_location}/SHA1")
# Check Hunter already downloaded by HunterGate
if(NOT EXISTS "${_done_location}")
hunter_gate_download("${_archive_id_location}")
endif()
if(NOT EXISTS "${_done_location}")
hunter_gate_internal_error("hunter_gate_download failed")
endif()
if(NOT EXISTS "${_sha1_location}")
hunter_gate_internal_error("${_sha1_location} not found")
endif()
file(READ "${_sha1_location}" _sha1_value)
string(TOLOWER "${_sha1_value}" _sha1_value_lower)
string(TOLOWER "${HUNTER_GATE_SHA1}" _HUNTER_GATE_SHA1_lower)
string(COMPARE EQUAL "${_sha1_value_lower}" "${_HUNTER_GATE_SHA1_lower}" _is_equal)
if(NOT _is_equal)
hunter_gate_internal_error(
"Short SHA1 collision:"
" ${_sha1_value} (from ${_sha1_location})"
" ${HUNTER_GATE_SHA1} (HunterGate)"
)
endif()
if(NOT EXISTS "${_master_location}")
hunter_gate_user_error(
"Master file not found:"
" ${_master_location}"
"try to update Hunter/HunterGate"
)
endif()
endif()
include("${_master_location}")
set_property(GLOBAL PROPERTY HUNTER_GATE_DONE YES)
endif()
endmacro()
@@ -1,12 +0,0 @@
set(COVERAGE_CMAKE "${CMAKE_BINARY_DIR}/cmake/CodeCoverage.cmake")
if(NOT EXISTS ${COVERAGE_CMAKE})
set(COVERAGE_URL "https://raw.githubusercontent.com/bilke/cmake-modules/master/CodeCoverage.cmake")
file(DOWNLOAD ${COVERAGE_URL} ${COVERAGE_CMAKE})
endif()
include(${COVERAGE_CMAKE})
function(setup_coverage TARGET)
target_compile_options(${TARGET} PRIVATE -g -O0 -fprofile-arcs -ftest-coverage)
target_link_libraries(${TARGET} PRIVATE gcov)
endfunction()
@@ -1,19 +0,0 @@
@PACKAGE_INIT@
set(JWT_EXTERNAL_PICOJSON @JWT_EXTERNAL_PICOJSON@)
set(JWT_SSL_LIBRARY @JWT_SSL_LIBRARY@)
include(CMakeFindDependencyMacro)
if(${JWT_SSL_LIBRARY} MATCHES "wolfSSL")
find_dependency(PkgConfig REQUIRED)
pkg_check_modules(wolfssl REQUIRED IMPORTED_TARGET wolfssl)
list(TRANSFORM wolfssl_INCLUDE_DIRS APPEND "/wolfssl") # This is required to access OpenSSL compatibility API
else()
find_dependency(${JWT_SSL_LIBRARY} REQUIRED)
endif()
if(JWT_EXTERNAL_PICOJSON)
find_dependency(picojson REQUIRED)
endif()
include("${CMAKE_CURRENT_LIST_DIR}/jwt-cpp-targets.cmake")
@@ -1,16 +0,0 @@
if(TARGET boost_json)
return()
endif()
unset(BOOSTJSON_INCLUDE_DIR CACHE)
find_path(BOOSTJSON_INCLUDE_DIR "boost/json.hpp" "boost/json/src.hpp")
if(EXISTS "${BOOSTJSON_INCLUDE_DIR}/boost/json.hpp")
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/private-boost-json.cpp.in" "#include <boost/json/src.hpp>")
configure_file("${CMAKE_CURRENT_BINARY_DIR}/private-boost-json.cpp.in" private-boost-json.cpp COPYONLY)
add_library(boost_json "${BOOSTJSON_INCLUDE_DIR}/boost/json.hpp"
"${BOOSTJSON_INCLUDE_DIR}/boost/json/src.hpp"
"${CMAKE_CURRENT_BINARY_DIR}/private-boost-json.cpp")
target_include_directories(boost_json PUBLIC ${BOOSTJSON_INCLUDE_DIR})
target_compile_definitions(boost_json PUBLIC BOOST_JSON_STANDALONE)
target_compile_features(boost_json PUBLIC cxx_std_17)
endif()
@@ -1,10 +0,0 @@
if(TARGET kazuho_picojson)
return()
endif()
unset(PICOJSON_INCLUDE_DIR CACHE)
find_path(PICOJSON_INCLUDE_DIR "picojson/picojson.h")
if(EXISTS "${PICOJSON_INCLUDE_DIR}/picojson/picojson.h")
add_library(kazuho_picojson INTERFACE)
target_include_directories(kazuho_picojson INTERFACE ${PICOJSON_INCLUDE_DIR})
endif()
-78
View File
@@ -1,78 +0,0 @@
# Frequently Asked Questions
## Handling Tokens
### The generated JWT token can be decoded, is this correct and secure?
This is the expected behavior. While the integrity of tokens is ensured by the generated/verified hash,
the contents of the token are only **encoded and not encrypted**. This means you can be sure the token
has not been modified by an unauthorized party, but you should not store confidential information in it.
Anyone with access to the token can read all the claims you put into it. They can however not modify
them unless they have the (private or symmetric) key used to generate the token. If you need to put
confidential information into it, current industry recommends generating a random id and store the data on your
server, using the id to look it up whenever you need.
### How can new keys be generated for my application?
The algorithms provided are all based on OpenSSL, mixing other
cryptographic tools might not work.
Here are a few links for your convenience:
- [RSA](https://stackoverflow.com/a/44474607)
- [ED25519](https://stackoverflow.com/a/73118582)
- [ES256](https://github.com/Thalhammer/jwt-cpp/blob/68309438cf30679d6581d6cfbfeea0c028d9ed04/example/es256k.cpp#L5)
### Can this library encrypt/decrypt claims?
No it does not, see [#115](https://github.com/Thalhammer/jwt-cpp/issues/115) for more details.
More importantly you probably don't want to be using JWTs for anything sensitive. Read [this](https://stackoverflow.com/a/43497242/8480874)
for more.
### Why are my tokens immediately expired?
If you are generating tokens that seem to immediately expire, you are likely mixing local time where it is not required. The JWT specification
requires using UTC which this library does.
Here is a simple example of creating a token that will expire in one hour:
```cpp
auto token = jwt::create()
.set_issued_at(std::chrono::system_clock::now())
.set_expires_at(std::chrono::system_clock::now() + std::chrono::seconds{3600})
.sign(jwt::algorithm::hs256{"secret"});
```
### Can you add claims to a signed token?
The signature includes both the header and payload, according to the RFCs... changing the payload would cause a discrepancy.
That should result in the token being rejected. For more details checkout [#194](https://github.com/Thalhammer/jwt-cpp/issues/194).
### Why does `jwt::basic_claim` have no `as_object()` method?
This was brought up in [#212](https://github.com/Thalhammer/jwt-cpp/issues/212#issuecomment-1054344192) and
[#101](https://github.com/Thalhammer/jwt-cpp/issues/101) as it's an excellent question.
It simply was not required to handle the required keys in JWTs for signing or verification. All the the mandatory keys
are numeric, string or array types which required type definitions and access.
The alternative is to use the `to_json()` method and use the libraries own APIs to pick the data type you need.
## Build Issues
### Missing \_HMAC and \_EVP_sha256 symbols on Mac
There seems to exists a problem with the included openssl library of MacOS. Make sure you link to one provided by brew.
See [#6](https://github.com/Thalhammer/jwt-cpp/issues/6) for more details.
### Building on windows fails with syntax errors
The header `<Windows.h>`, which is often included in Windows projects, defines macros for MIN and MAX which conflicts
with `std::numeric_limits`. See [#5](https://github.com/Thalhammer/jwt-cpp/issues/5) for more details or
[this StackOverflow thread](https://stackoverflow.com/questions/13416418/define-nominmax-using-stdmin-max).
To fix this do one of the following things:
* define `NOMINMAX`, which suppresses this behavior
* include this library before you `#include <Windows.h>`
* place `#undef max` and `#undef min` before you include this library
-34
View File
@@ -1,34 +0,0 @@
# Signing Tokens
## Custom Signature Algorithms
The libraries design is open so you can implement your own algorithms, see [existing examples](https://github.com/Thalhammer/jwt-cpp/blob/73f23419235661e89a304ba5ab09d6714fb8dd94/include/jwt-cpp/jwt.h#L874) for ideas.
```cpp
struct your_algorithm{
std::string sign(const std::string& /*unused*/, std::error_code& ec) const {
ec.clear();
// CALL YOUR METHOD HERE
return {};
}
void verify(const std::string& /*unused*/, const std::string& signature, std::error_code& ec) const {
ec.clear();
if (!signature.empty()) { ec = error::signature_verification_error::invalid_signature; }
// CALL YOUR METHOD HERE
}
std::string name() const { return "your_algorithm"; }
};
```
Then everything else is the same, just pass in your implementation such as:
```cpp
auto token = jwt::create()
.set_id("custom-algo-example")
.set_issued_at(std::chrono::system_clock::now())
.set_expires_at(std::chrono::system_clock::now() + std::chrono::seconds{36000})
.set_payload_claim("sample", jwt::claim(std::string{"test"}))
.sign(your_algorithm{/* what ever you want */});
```
-19
View File
@@ -1,19 +0,0 @@
# Cryptography Libraries
The underlying cryptography libraries describe [here](../README.md#ssl-compatibility) can be selected when
configuring CMake by explicitly setting `JWT_SSL_LIBRARY` to one of three values. The default is to use OpenSSL.
- OpenSSL
- LibreSSL
- wolfSSL
Here's an example:
```sh
cmake . -DJWT_SSL_LIBRARY:STRING=wolfSSL
```
## Notes
JWT-CPP relies on the OpenSSL API, as a result both LibreSSL and wolfSSL need to include their respective compatibility layers.
Most system already have OpenSSL so it's important to make sure when compiling your application it only includes one. Otherwise you may have missing symbols when linking.
-60
View File
@@ -1,60 +0,0 @@
# JSON Traits
Traits define the compatibility mapping for JWT-CPP required functionality to the JSON implementation of choice.
## Providing your own JSON Traits
There are several key items that need to be provided to a `jwt::basic_claim` in order for it to be interoperable with you JSON library of choice.
* type specifications
* conversion from generic "value type" to a specific type
* serialization and parsing
If ever you are not sure, the traits are heavily checked against static asserts to make sure you provide everything that's required.
> :warning: Not all JSON libraries are a like, you may need to extend certain types such that it can be used. See this [provided implementation](https://github.com/Thalhammer/jwt-cpp/blob/e6b92cca0b7088027269c481fa244e5c39df88ff/include/jwt-cpp/traits/danielaparker-jsoncons/traits.h#L18).
```cpp
struct my_favorite_json_library_traits {
// Type Specifications
using value_type = json; // The generic "value type" implementation, most libraries have one
using object_type = json::object_t; // The "map type" string to value
using array_type = json::array_t; // The "list type" array of values
using string_type = std::string; // The "list of chars", must be a narrow char
using number_type = double; // The "precision type"
using integer_type = int64_t; // The "integral type"
using boolean_type = bool; // The "boolean type"
// Translation between the implementation notion of type, to the jwt::json::type equivalent
static jwt::json::type get_type(const value_type &val) {
using jwt::json::type;
if (val.type() == json::value_t::object)
return type::object;
if (val.type() == json::value_t::array)
return type::array;
if (val.type() == json::value_t::string)
return type::string;
if (val.type() == json::value_t::number_float)
return type::number;
if (val.type() == json::value_t::number_integer)
return type::integer;
if (val.type() == json::value_t::boolean)
return type::boolean;
throw std::logic_error("invalid type");
}
// Conversion from generic value to specific type
static object_type as_object(const value_type &val);
static array_type as_array(const value_type &val);
static string_type as_string(const value_type &val);
static number_type as_number(const value_type &val);
static integer_type as_integer(const value_type &val);
static boolean_type as_boolean(const value_type &val);
// serialization and parsing
static bool parse(value_type &val, string_type str);
static string_type serialize(const value_type &val); // with no extra whitespace, padding or indentation
};
```
@@ -1,33 +0,0 @@
cmake_minimum_required(VERSION 3.8)
project(jwt-cpp-examples)
if(NOT TARGET jwt-cpp)
find_package(jwt-cpp CONFIG REQUIRED)
endif()
add_subdirectory(traits)
if(JWT_DISABLE_PICOJSON)
message(FATAL_ERROR "examples require picojson to be available!")
endif()
add_executable(print-claims print-claims.cpp)
target_link_libraries(print-claims jwt-cpp::jwt-cpp)
add_executable(private-claims private-claims.cpp)
target_link_libraries(private-claims jwt-cpp::jwt-cpp)
add_executable(rsa-create rsa-create.cpp)
target_link_libraries(rsa-create jwt-cpp::jwt-cpp)
add_executable(rsa-verify rsa-verify.cpp)
target_link_libraries(rsa-verify jwt-cpp::jwt-cpp)
add_executable(jwks-verify jwks-verify.cpp)
target_link_libraries(jwks-verify jwt-cpp::jwt-cpp)
add_executable(es256k es256k.cpp)
target_link_libraries(es256k jwt-cpp::jwt-cpp)
add_executable(partial-claim-verifier partial-claim-verifier.cpp)
target_link_libraries(partial-claim-verifier jwt-cpp::jwt-cpp nlohmann_json::nlohmann_json)
@@ -1,8 +0,0 @@
cmake_minimum_required(VERSION 3.8)
project(conan-example)
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()
add_executable(${PROJECT_NAME} main.cpp)
target_link_libraries(${PROJECT_NAME} ${CONAN_LIBS})
@@ -1,24 +0,0 @@
# Conan example
In the current directory on Linux environment
```sh
mkdir build && cd build
conan install .. && cmake ..
cmake --build .
```
run executable
```sh
$ ./bin/conan-example
sub = "jrocket@example.com"
iss = "Online JWT Builder"
exp = 1641559177
aud = "www.example.com"
Surname = "Rocket"
Role = ["Manager","Project Administrator"]
iat = 1610023177
GivenName = "Johnny"
Email = "jrocket@example.com"
```
@@ -1,6 +0,0 @@
[requires]
jwt-cpp/0.6.0
picojson/cci.20210117
[generators]
cmake
@@ -1,17 +0,0 @@
#include "jwt-cpp/jwt.h"
#include <chrono>
#include <iostream>
int main() {
std::string token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9."
"eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE2MTAwMjMxNzcsImV4cCI6MTY0MTU1OTE3NywiYXVkIjoid3"
"d3LmV4YW1wbGUuY29tIiwic3ViIjoianJvY2tldEBleGFtcGxlLmNvbSIsIkdpdmVuTmFtZSI6IkpvaG5ueSIsIlN1cm5h"
"bWUiOiJSb2NrZXQiLCJFbWFpbCI6Impyb2NrZXRAZXhhbXBsZS5jb20iLCJSb2xlIjpbIk1hbmFnZXIiLCJQcm9qZWN0IE"
"FkbWluaXN0cmF0b3IiXX0.5EOfHnBmpdPvRHAuVDttgJQvbFuGEF7fC4uBSXAGg6c";
auto decoded = jwt::decode(token);
for (auto& e : decoded.get_payload_json())
std::cout << e.first << " = " << e.second << std::endl;
}
-40
View File
@@ -1,40 +0,0 @@
#include <iostream>
#include <jwt-cpp/jwt.h>
int main() {
// openssl ecparam -name secp256k1 -genkey -noout -out ec-secp256k1-priv-key.pem
std::string es256k_priv_key = R"(-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIArnQWnspKtjiVuZuzuZ/l1Uqqq8gb2unLJ/6U/Saf4ioAcGBSuBBAAK
oUQDQgAEfy03KCKUpIPMIJBtIG4xOwGm0Np/yHKaK9EDZi0mZ7VUeeNKq476CU5X
940yusahgneePQrDMF2nWFEtBCOiXQ==
-----END EC PRIVATE KEY-----)";
// openssl ec -in ec-secp256k1-priv-key.pem -pubout > ec-secp256k1-pub-key.pem
std::string es256k_pub_key = R"(-----BEGIN PUBLIC KEY-----
MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEfy03KCKUpIPMIJBtIG4xOwGm0Np/yHKa
K9EDZi0mZ7VUeeNKq476CU5X940yusahgneePQrDMF2nWFEtBCOiXQ==
-----END PUBLIC KEY-----)";
auto token = jwt::create()
.set_issuer("auth0")
.set_type("JWT")
.set_id("es256k-create-example")
.set_issued_at(std::chrono::system_clock::now())
.set_expires_at(std::chrono::system_clock::now() + std::chrono::seconds{36000})
.set_payload_claim("sample", jwt::claim(std::string{"test"}))
.sign(jwt::algorithm::es256k(es256k_pub_key, es256k_priv_key, "", ""));
std::cout << "token:\n" << token << std::endl;
auto verify = jwt::verify()
.allow_algorithm(jwt::algorithm::es256k(es256k_pub_key, es256k_priv_key, "", ""))
.with_issuer("auth0");
auto decoded = jwt::decode(token);
verify.verify(decoded);
for (auto& e : decoded.get_header_json())
std::cout << e.first << " = " << e.second << std::endl;
for (auto& e : decoded.get_payload_json())
std::cout << e.first << " = " << e.second << std::endl;
}
@@ -1,57 +0,0 @@
#include <iostream>
#include <jwt-cpp/jwt.h>
int main() {
std::string raw_jwks =
R"({"keys": [{
"kid":"internal-gateway-jwt.api.sc.net",
"alg": "RS256",
"kty": "RSA",
"use": "sig",
"x5c": [
"MIIC+DCCAeCgAwIBAgIJBIGjYW6hFpn2MA0GCSqGSIb3DQEBBQUAMCMxITAfBgNVBAMTGGN1c3RvbWVyLWRlbW9zLmF1dGgwLmNvbTAeFw0xNjExMjIyMjIyMDVaFw0zMDA4MDEyMjIyMDVaMCMxITAfBgNVBAMTGGN1c3RvbWVyLWRlbW9zLmF1dGgwLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMnjZc5bm/eGIHq09N9HKHahM7Y31P0ul+A2wwP4lSpIwFrWHzxw88/7Dwk9QMc+orGXX95R6av4GF+Es/nG3uK45ooMVMa/hYCh0Mtx3gnSuoTavQEkLzCvSwTqVwzZ+5noukWVqJuMKNwjL77GNcPLY7Xy2/skMCT5bR8UoWaufooQvYq6SyPcRAU4BtdquZRiBT4U5f+4pwNTxSvey7ki50yc1tG49Per/0zA4O6Tlpv8x7Red6m1bCNHt7+Z5nSl3RX/QYyAEUX1a28VcYmR41Osy+o2OUCXYdUAphDaHo4/8rbKTJhlu8jEcc1KoMXAKjgaVZtG/v5ltx6AXY0CAwEAAaMvMC0wDAYDVR0TBAUwAwEB/zAdBgNVHQ4EFgQUQxFG602h1cG+pnyvJoy9pGJJoCswDQYJKoZIhvcNAQEFBQADggEBAGvtCbzGNBUJPLICth3mLsX0Z4z8T8iu4tyoiuAshP/Ry/ZBnFnXmhD8vwgMZ2lTgUWwlrvlgN+fAtYKnwFO2G3BOCFw96Nm8So9sjTda9CCZ3dhoH57F/hVMBB0K6xhklAc0b5ZxUpCIN92v/w+xZoz1XQBHe8ZbRHaP1HpRM4M7DJk2G5cgUCyu3UBvYS41sHvzrxQ3z7vIePRA4WF4bEkfX12gvny0RsPkrbVMXX1Rj9t6V7QXrbPYBAO+43JvDGYawxYVvLhz+BJ45x50GFQmHszfY3BR9TPK8xmMmQwtIvLu1PMttNCs7niCYkSiUv2sc2mlq1i3IashGkkgmo="
],
"n": "yeNlzlub94YgerT030codqEztjfU_S6X4DbDA_iVKkjAWtYfPHDzz_sPCT1Axz6isZdf3lHpq_gYX4Sz-cbe4rjmigxUxr-FgKHQy3HeCdK6hNq9ASQvMK9LBOpXDNn7mei6RZWom4wo3CMvvsY1w8tjtfLb-yQwJPltHxShZq5-ihC9irpLI9xEBTgG12q5lGIFPhTl_7inA1PFK97LuSLnTJzW0bj096v_TMDg7pOWm_zHtF53qbVsI0e3v5nmdKXdFf9BjIARRfVrbxVxiZHjU6zL6jY5QJdh1QCmENoejj_ytspMmGW7yMRxzUqgxcAqOBpVm0b-_mW3HoBdjQ",
"e": "AQAB",
"x5t": "NjVBRjY5MDlCMUIwNzU4RTA2QzZFMDQ4QzQ2MDAyQjVDNjk1RTM2Qg"
},
{
"kid":"internal-123456",
"use":"sig",
"x5c":["MIIG1TCCBL2gAwIBAgIIFvMVGp6t\/cMwDQYJKoZIhvcNAQELBQAwZjELMAkGA1UEBhMCR0IxIDAeBgNVBAoMF1N0YW5kYXJkIENoYXJ0ZXJlZCBCYW5rMTUwMwYDVQQDDCxTdGFuZGFyZCBDaGFydGVyZWQgQmFuayBTaWduaW5nIENBIEcxIC0gU0hBMjAeFw0xODEwMTAxMTI2MzVaFw0yMjEwMTAxMTI2MzVaMIG9MQswCQYDVQQGEwJTRzESMBAGA1UECAwJU2luZ2Fwb3JlMRIwEAYDVQQHDAlTaW5nYXBvcmUxIDAeBgNVBAoMF1N0YW5kYXJkIENoYXJ0ZXJlZCBCYW5rMRwwGgYDVQQLDBNGb3VuZGF0aW9uIFNlcnZpY2VzMSgwJgYDVQQDDB9pbnRlcm5hbC1nYXRld2F5LWp3dC5hcGkuc2MubmV0MRwwGgYJKoZIhvcNAQkBFg1BUElQU1NAc2MuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArVWBoIi3IJ4nOWXu7\/SDxczqMou1B+c4c2FdQrOXrK31HxAaz4WEtma9BLXFdFHJ5mCCPIvdUcVxxnCynqhMOkZ\/a7acQbUD9cDzI8isMB9JL7VooDw0CctxHxffjqQQVIEhC2Q7zsM1pQayR7cl+pbBlvHIoRxq2n1B0fFvfoiosjf4kDiCpgHdM+v5Hw9aVYmUbroHxmQWqhB0iRTJQPPLZqqQVC50A1Q\/96gkwoODyotc46Uy9wYEpdGrtDG\/thWay3fmMsjpWR0U25xFIrxTrfCGBblYpD7juukWWml2E9rtE2rHgUxbymxXjEw7xrMwcGrhOGyqwoBqJy1JVwIDAQABo4ICLTCCAikwZAYIKwYBBQUHAQEEWDBWMFQGCCsGAQUFBzABhkhodHRwOi8vY29yZW9jc3AuZ2xvYmFsLnN0YW5kYXJkY2hhcnRlcmVkLmNvbS9lamJjYS9wdWJsaWN3ZWIvc3RhdHVzL29jc3AwHQYDVR0OBBYEFIinW4BNDeVEFcuLf8YjZjtySoW9MAwGA1UdEwEB\/wQCMAAwHwYDVR0jBBgwFoAUfNZMoZi33nKrcmVU3TFVQnuEi\/4wggFCBgNVHR8EggE5MIIBNTCCATGggcKggb+GgbxodHRwOi8vY29yZWNybC5nbG9iYWwuc3RhbmRhcmRjaGFydGVyZWQuY29tL2VqYmNhL3B1YmxpY3dlYi93ZWJkaXN0L2NlcnRkaXN0P2NtZD1jcmwmaXNzdWVyPUNOPVN0YW5kYXJkJTIwQ2hhcnRlcmVkJTIwQmFuayUyMFNpZ25pbmclMjBDQSUyMEcxJTIwLSUyMFNIQTIsTz1TdGFuZGFyZCUyMENoYXJ0ZXJlZCUyMEJhbmssQz1HQqJqpGgwZjE1MDMGA1UEAwwsU3RhbmRhcmQgQ2hhcnRlcmVkIEJhbmsgU2lnbmluZyBDQSBHMSAtIFNIQTIxIDAeBgNVBAoMF1N0YW5kYXJkIENoYXJ0ZXJlZCBCYW5rMQswCQYDVQQGEwJHQjAOBgNVHQ8BAf8EBAMCBsAwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMA0GCSqGSIb3DQEBCwUAA4ICAQBtsoRlDHuOTDChcWdfdVUtRgP0U0ijDSeJi8vULN1rgYnqqJc4PdJno50aiu9MGlxY02O7HW7ZVD6QEG\/pqHmZ0sbWpb\/fumMgZSjP65IcGuS53zgcNtLYnyXyEv+v5T\/CK3bk4Li6tUW3ScJPUwVWwP1E0\/u6aBSb5k\/h4lTwS1o88ybS5pJOg6XutXByp991QQrrs7tp7fKNynjNZbFuG3J1e09X+zTfJOpjaDUofQTkt8IyMRI6Cs4wI1eZA+dAIL8B0n8ze1mRl1FOJqgdZrAQjoqZkCTnc0Il5VY\/dUXxGVg6D9e5pfck3FWT107K9\/5EZoxytpqYXFCjMXi5hx4YjK17OUgm82mZhvqkNdzF8Yq2vFuB3LPfyelESq99xFLykvinrVm1NtZKeDTT1Jq\/VvZt6stO\/tovq1RfJJcznpYcwOzxlnhGR6E+hxuBx7aDJzGf0JaoRxQILH1B2XV9WDI3HPYQsP7XtriX+QUJ\/aly28QkV48RmaGYCsly43YZu1MKudSsw+dhnbZzRsg\/aes3dzGW2x137bQPtux7k2LCSpsTXgedhOys28YoGlsoe8kUv0myAU4Stt+I3mrwO3BKUn+tJggvlDiiiyT1tg2HiklyU\/2FxQkZRMeB0eRrXTpg3l9x2mpF+dDFxOMKszxwD2kgoEZgo6o58A=="],
"n":"nr9UsxnPVd21iuiGcIJ_Qli2XVlAZe5VbELA1hO2-L4k5gI4fjHZ3ysUcautLpbOYogOQgsnlpsLrCmvNDvBDVzVp2nMbpguJlt12vHSP1fRJJpipGQ8qU-VaXsC4OjOQf3H9ojAU5Vfnl5gZ7kVCd8g4M29l-IRyNpxE-Ccxc2Y7molsCHT6GHLMMBVsd11JIOXMICJf4hz2YYkQ1t7C8SaB2RFRPuGO5Mn6mfAnwdmRera4TBz6_pIPPCgCbN8KOdJItWkr9F7Tjv_0nhh-ZVlQvbQ9PXHyKTj00g3IYUlbZIWHm0Ley__fzNZk2dyAAVjNA2QSzTZJc33MQx1pQ",
"e":"AQAB",
"x5t":"-qC0akuyiHTV5aFsKVWM9da7lzq6DLrj09I",
"alg":"RS256",
"kty":"RSA"
}
]})";
std::string token =
"eyJraWQiOiJpbnRlcm5hbC1nYXRld2F5LWp3dC5hcGkuc2MubmV0IiwiYWxnIjoiUlMyNTYiLCJ0eXAiOiJKV1QifQ."
"eyJuYmYiOjE1Mzk3NjcwMTUsImlhdCI6MTUzOTc2Njk5MiwiaXNzIjoia29uZyIsImh0dHA6XC9cL3dzbzIub3JnXC9nYXRld2F5XC9zdWJzY3"
"JpYmVyIjoidXZ0dXNlcjJAY2FyYm9uLnN1cGVyIiwib3JpZ2luYWxfaXNzIjoiaHR0cDpcL1wvd3NvMi5vcmdcL2dhdGV3YXkiLCJzdWIiOiJ1"
"dnR1c2VyMkBjYXJib24uc3VwZXIiLCJodHRwOlwvXC93c28yLm9yZ1wvZ2F0ZXdheVwvZW5kdXNlciI6InV2dHVzZXIyQGNhcmJvbi5zdXBlci"
"IsImp0aSI6IjI0NmJkZTlhLWQ4OGQtNGRlZC1hODhmLTRhMTNhOWJmODQ4ZiIsImh0dHA6XC9cL3dzbzIub3JnXC9nYXRld2F5XC9hcHBsaWNh"
"dGlvbm5hbWUiOiJ1dnR1c2VyMl9hcHBfMSIsImV4cCI6MTUzOTc2NzkxNX0.foxbo6C30yr_wkF-5EkgtYUMG-4SXNfRsmewdT6MbE-"
"RXVkIPkVk8kDP41yRXmnk4OxburCqawiGlzzEhfHoFf0qv0qZEmwEXSdcyRw-czZTs6ACjWYe8kejOCVmpvUrq01NgOhTwgVg6pv93BlcmNY--"
"zytjx_9hlVm5SS1lZ0I21n45BIWu5JvBD51TZXEURb_XhL7RcF9I8mfzrRpB2fSHW38gj-nogsdOPA_y3S-hJKylmmaqmaQgTF-jP-"
"gYr6eqKyGPVwc6fLZ5zqAup59SefdPEY23-WWmHzj968jlsDSEiCp_YiYTnF3tHVLFWDsrprYKwNb0_p95tBmPA";
auto decoded_jwt = jwt::decode(token);
auto jwks = jwt::parse_jwks(raw_jwks);
auto jwk = jwks.get_jwk(decoded_jwt.get_key_id());
auto issuer = decoded_jwt.get_issuer();
auto x5c = jwk.get_x5c_key_value();
if (!x5c.empty() && !issuer.empty()) {
auto verifier =
jwt::verify()
.allow_algorithm(jwt::algorithm::rs256(jwt::helper::convert_base64_der_to_pem(x5c), "", "", ""))
.with_issuer(issuer)
.leeway(60UL); // value in seconds, add some to compensate timeout
verifier.verify(decoded_jwt);
}
}
@@ -1,91 +0,0 @@
#include "jwt-cpp/traits/nlohmann-json/defaults.h"
#include <iostream>
int main() {
std::string rsa_priv_key = R"(-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC4ZtdaIrd1BPIJ
tfnF0TjIK5inQAXZ3XlCrUlJdP+XHwIRxdv1FsN12XyMYO/6ymLmo9ryoQeIrsXB
XYqlET3zfAY+diwCb0HEsVvhisthwMU4gZQu6TYW2s9LnXZB5rVtcBK69hcSlA2k
ZudMZWxZcj0L7KMfO2rIvaHw/qaVOE9j0T257Z8Kp2CLF9MUgX0ObhIsdumFRLaL
DvDUmBPr2zuh/34j2XmWwn1yjN/WvGtdfhXW79Ki1S40HcWnygHgLV8sESFKUxxQ
mKvPUTwDOIwLFL5WtE8Mz7N++kgmDcmWMCHc8kcOIu73Ta/3D4imW7VbKgHZo9+K
3ESFE3RjAgMBAAECggEBAJTEIyjMqUT24G2FKiS1TiHvShBkTlQdoR5xvpZMlYbN
tVWxUmrAGqCQ/TIjYnfpnzCDMLhdwT48Ab6mQJw69MfiXwc1PvwX1e9hRscGul36
ryGPKIVQEBsQG/zc4/L2tZe8ut+qeaK7XuYrPp8bk/X1e9qK5m7j+JpKosNSLgJj
NIbYsBkG2Mlq671irKYj2hVZeaBQmWmZxK4fw0Istz2WfN5nUKUeJhTwpR+JLUg4
ELYYoB7EO0Cej9UBG30hbgu4RyXA+VbptJ+H042K5QJROUbtnLWuuWosZ5ATldwO
u03dIXL0SH0ao5NcWBzxU4F2sBXZRGP2x/jiSLHcqoECgYEA4qD7mXQpu1b8XO8U
6abpKloJCatSAHzjgdR2eRDRx5PMvloipfwqA77pnbjTUFajqWQgOXsDTCjcdQui
wf5XAaWu+TeAVTytLQbSiTsBhrnoqVrr3RoyDQmdnwHT8aCMouOgcC5thP9vQ8Us
rVdjvRRbnJpg3BeSNimH+u9AHgsCgYEA0EzcbOltCWPHRAY7B3Ge/AKBjBQr86Kv
TdpTlxePBDVIlH+BM6oct2gaSZZoHbqPjbq5v7yf0fKVcXE4bSVgqfDJ/sZQu9Lp
PTeV7wkk0OsAMKk7QukEpPno5q6tOTNnFecpUhVLLlqbfqkB2baYYwLJR3IRzboJ
FQbLY93E8gkCgYB+zlC5VlQbbNqcLXJoImqItgQkkuW5PCgYdwcrSov2ve5r/Acz
FNt1aRdSlx4176R3nXyibQA1Vw+ztiUFowiP9WLoM3PtPZwwe4bGHmwGNHPIfwVG
m+exf9XgKKespYbLhc45tuC08DATnXoYK7O1EnUINSFJRS8cezSI5eHcbQKBgQDC
PgqHXZ2aVftqCc1eAaxaIRQhRmY+CgUjumaczRFGwVFveP9I6Gdi+Kca3DE3F9Pq
PKgejo0SwP5vDT+rOGHN14bmGJUMsX9i4MTmZUZ5s8s3lXh3ysfT+GAhTd6nKrIE
kM3Nh6HWFhROptfc6BNusRh1kX/cspDplK5x8EpJ0QKBgQDWFg6S2je0KtbV5PYe
RultUEe2C0jYMDQx+JYxbPmtcopvZQrFEur3WKVuLy5UAy7EBvwMnZwIG7OOohJb
vkSpADK6VPn9lbqq7O8cTedEHttm6otmLt8ZyEl3hZMaL3hbuRj6ysjmoFKx6CrX
rK0/Ikt5ybqUzKCMJZg2VKGTxg==
-----END PRIVATE KEY-----)";
auto role_claim = nlohmann::json{{"my-service", {{"roles", {"foo", "bar", "baz"}}}}};
auto token = jwt::create()
.set_issuer("auth0")
.set_type("JWT")
.set_id("rsa-create-example")
.set_issued_at(std::chrono::system_clock::now())
.set_expires_at(std::chrono::system_clock::now() + std::chrono::seconds{36000})
.set_payload_claim("resource-access", role_claim)
.sign(jwt::algorithm::rs256("", rsa_priv_key, "", ""));
std::cout << "token: " << token << std::endl;
std::string rsa_pub_key = R"(-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuGbXWiK3dQTyCbX5xdE4
yCuYp0AF2d15Qq1JSXT/lx8CEcXb9RbDddl8jGDv+spi5qPa8qEHiK7FwV2KpRE9
83wGPnYsAm9BxLFb4YrLYcDFOIGULuk2FtrPS512Qea1bXASuvYXEpQNpGbnTGVs
WXI9C+yjHztqyL2h8P6mlThPY9E9ue2fCqdgixfTFIF9Dm4SLHbphUS2iw7w1JgT
69s7of9+I9l5lsJ9cozf1rxrXX4V1u/SotUuNB3Fp8oB4C1fLBEhSlMcUJirz1E8
AziMCxS+VrRPDM+zfvpIJg3JljAh3PJHDiLu902v9w+Iplu1WyoB2aPfitxEhRN0
YwIDAQAB
-----END PUBLIC KEY-----)";
auto decoded = jwt::decode(token);
for (const auto& e : decoded.get_payload_json())
std::cout << e.first << " = " << e.second << std::endl;
std::cout << std::endl;
auto role_verifier = [](const jwt::verify_context& ctx, std::error_code& ec) {
using error = jwt::error::token_verification_error;
auto c = ctx.get_claim(false, ec);
if (ec) return;
if (c.get_type() == jwt::json::type::object) {
auto obj = c.to_json();
try {
auto roles = obj["my-service"]["roles"].get<nlohmann::json::array_t>();
if (roles.end() == std::find(roles.begin(), roles.end(), "foo")) ec = error::claim_value_missmatch;
} catch (const std::exception& ex) { ec = error::claim_value_missmatch; }
} else
ec = error::claim_type_missmatch;
};
auto verifier = jwt::verify()
.allow_algorithm(jwt::algorithm::rs256(rsa_pub_key, "", "", ""))
.with_issuer("auth0")
.with_claim("resource-access", role_verifier);
try {
verifier.verify(decoded);
std::cout << "Success!" << std::endl;
} catch (const std::exception& ex) { std::cout << "Error: " << ex.what() << std::endl; }
return 0;
}
@@ -1,11 +0,0 @@
#include <iostream>
#include <jwt-cpp/jwt.h>
int main() {
std::string token =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCJ9.AbIJTDMFc7yUa5MhvcP03nJPyCPzZtQcGEp-zWfOkEE";
auto decoded = jwt::decode(token);
for (auto& e : decoded.get_payload_json())
std::cout << e.first << " = " << e.second << std::endl;
}
@@ -1,46 +0,0 @@
#include <jwt-cpp/jwt.h>
#include <iostream>
#include <sstream>
using sec = std::chrono::seconds;
using min = std::chrono::minutes;
int main() {
jwt::claim from_raw_json;
std::istringstream iss{R"##({"api":{"array":[1,2,3],"null":null}})##"};
iss >> from_raw_json;
jwt::claim::set_t list{"once", "twice"};
std::vector<int64_t> big_numbers{727663072ULL, 770979831ULL, 427239169ULL, 525936436ULL};
const auto time = jwt::date::clock::now();
const auto token = jwt::create()
.set_type("JWT")
.set_issuer("auth.mydomain.io")
.set_audience("mydomain.io")
.set_issued_at(time)
.set_not_before(time + sec{15})
.set_expires_at(time + sec{15} + min{2})
.set_payload_claim("boolean", picojson::value(true))
.set_payload_claim("integer", picojson::value(int64_t{12345}))
.set_payload_claim("precision", picojson::value(12.345))
.set_payload_claim("strings", jwt::claim(list))
.set_payload_claim("array", jwt::claim(big_numbers.begin(), big_numbers.end()))
.set_payload_claim("object", from_raw_json)
.sign(jwt::algorithm::none{});
const auto decoded = jwt::decode(token);
const auto api_array = decoded.get_payload_claim("object").to_json().get("api").get("array");
std::cout << "api array = " << api_array << std::endl;
jwt::verify()
.allow_algorithm(jwt::algorithm::none{})
.with_issuer("auth.mydomain.io")
.with_audience("mydomain.io")
.with_claim("object", from_raw_json)
.verify(decoded);
return 0;
}
@@ -1,44 +0,0 @@
#include <iostream>
#include <jwt-cpp/jwt.h>
int main() {
std::string rsa_priv_key = R"(-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC4ZtdaIrd1BPIJ
tfnF0TjIK5inQAXZ3XlCrUlJdP+XHwIRxdv1FsN12XyMYO/6ymLmo9ryoQeIrsXB
XYqlET3zfAY+diwCb0HEsVvhisthwMU4gZQu6TYW2s9LnXZB5rVtcBK69hcSlA2k
ZudMZWxZcj0L7KMfO2rIvaHw/qaVOE9j0T257Z8Kp2CLF9MUgX0ObhIsdumFRLaL
DvDUmBPr2zuh/34j2XmWwn1yjN/WvGtdfhXW79Ki1S40HcWnygHgLV8sESFKUxxQ
mKvPUTwDOIwLFL5WtE8Mz7N++kgmDcmWMCHc8kcOIu73Ta/3D4imW7VbKgHZo9+K
3ESFE3RjAgMBAAECggEBAJTEIyjMqUT24G2FKiS1TiHvShBkTlQdoR5xvpZMlYbN
tVWxUmrAGqCQ/TIjYnfpnzCDMLhdwT48Ab6mQJw69MfiXwc1PvwX1e9hRscGul36
ryGPKIVQEBsQG/zc4/L2tZe8ut+qeaK7XuYrPp8bk/X1e9qK5m7j+JpKosNSLgJj
NIbYsBkG2Mlq671irKYj2hVZeaBQmWmZxK4fw0Istz2WfN5nUKUeJhTwpR+JLUg4
ELYYoB7EO0Cej9UBG30hbgu4RyXA+VbptJ+H042K5QJROUbtnLWuuWosZ5ATldwO
u03dIXL0SH0ao5NcWBzxU4F2sBXZRGP2x/jiSLHcqoECgYEA4qD7mXQpu1b8XO8U
6abpKloJCatSAHzjgdR2eRDRx5PMvloipfwqA77pnbjTUFajqWQgOXsDTCjcdQui
wf5XAaWu+TeAVTytLQbSiTsBhrnoqVrr3RoyDQmdnwHT8aCMouOgcC5thP9vQ8Us
rVdjvRRbnJpg3BeSNimH+u9AHgsCgYEA0EzcbOltCWPHRAY7B3Ge/AKBjBQr86Kv
TdpTlxePBDVIlH+BM6oct2gaSZZoHbqPjbq5v7yf0fKVcXE4bSVgqfDJ/sZQu9Lp
PTeV7wkk0OsAMKk7QukEpPno5q6tOTNnFecpUhVLLlqbfqkB2baYYwLJR3IRzboJ
FQbLY93E8gkCgYB+zlC5VlQbbNqcLXJoImqItgQkkuW5PCgYdwcrSov2ve5r/Acz
FNt1aRdSlx4176R3nXyibQA1Vw+ztiUFowiP9WLoM3PtPZwwe4bGHmwGNHPIfwVG
m+exf9XgKKespYbLhc45tuC08DATnXoYK7O1EnUINSFJRS8cezSI5eHcbQKBgQDC
PgqHXZ2aVftqCc1eAaxaIRQhRmY+CgUjumaczRFGwVFveP9I6Gdi+Kca3DE3F9Pq
PKgejo0SwP5vDT+rOGHN14bmGJUMsX9i4MTmZUZ5s8s3lXh3ysfT+GAhTd6nKrIE
kM3Nh6HWFhROptfc6BNusRh1kX/cspDplK5x8EpJ0QKBgQDWFg6S2je0KtbV5PYe
RultUEe2C0jYMDQx+JYxbPmtcopvZQrFEur3WKVuLy5UAy7EBvwMnZwIG7OOohJb
vkSpADK6VPn9lbqq7O8cTedEHttm6otmLt8ZyEl3hZMaL3hbuRj6ysjmoFKx6CrX
rK0/Ikt5ybqUzKCMJZg2VKGTxg==
-----END PRIVATE KEY-----)";
auto token = jwt::create()
.set_issuer("auth0")
.set_type("JWT")
.set_id("rsa-create-example")
.set_issued_at(std::chrono::system_clock::now())
.set_expires_at(std::chrono::system_clock::now() + std::chrono::seconds{36000})
.set_payload_claim("sample", jwt::claim(std::string{"test"}))
.sign(jwt::algorithm::rs256("", rsa_priv_key, "", ""));
std::cout << "token:\n" << token << std::endl;
}
@@ -1,34 +0,0 @@
#include <iostream>
#include <jwt-cpp/jwt.h>
int main() {
std::string rsa_pub_key = R"(-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuGbXWiK3dQTyCbX5xdE4
yCuYp0AF2d15Qq1JSXT/lx8CEcXb9RbDddl8jGDv+spi5qPa8qEHiK7FwV2KpRE9
83wGPnYsAm9BxLFb4YrLYcDFOIGULuk2FtrPS512Qea1bXASuvYXEpQNpGbnTGVs
WXI9C+yjHztqyL2h8P6mlThPY9E9ue2fCqdgixfTFIF9Dm4SLHbphUS2iw7w1JgT
69s7of9+I9l5lsJ9cozf1rxrXX4V1u/SotUuNB3Fp8oB4C1fLBEhSlMcUJirz1E8
AziMCxS+VrRPDM+zfvpIJg3JljAh3PJHDiLu902v9w+Iplu1WyoB2aPfitxEhRN0
YwIDAQAB
-----END PUBLIC KEY-----)";
std::string token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCJ9."
"VA2i1ui1cnoD6I3wnji1WAVCf29EekysvevGrT2GXqK1dDMc8"
"HAZCTQxa1Q8NppnpYV-hlqxh-X3Bb0JOePTGzjynpNZoJh2aHZD-"
"GKpZt7OO1Zp8AFWPZ3p8Cahq8536fD8RiBES9jRsvChZvOqA7gMcFc4"
"YD0iZhNIcI7a654u5yPYyTlf5kjR97prCf_OXWRn-bYY74zna4p_bP9oWCL4BkaoRcMxi-"
"IR7kmVcCnvbYqyIrKloXP2qPO442RBGqU7Ov9"
"sGQxiVqtRHKXZR9RbfvjrErY1KGiCp9M5i2bsUHadZEY44FE2jiOmx-"
"uc2z5c05CCXqVSpfCjWbh9gQ";
auto verify = jwt::verify().allow_algorithm(jwt::algorithm::rs256(rsa_pub_key, "", "", "")).with_issuer("auth0");
auto decoded = jwt::decode(token);
verify.verify(decoded);
for (auto& e : decoded.get_header_json())
std::cout << e.first << " = " << e.second << std::endl;
for (auto& e : decoded.get_payload_json())
std::cout << e.first << " = " << e.second << std::endl;
}
@@ -1,30 +0,0 @@
cmake_minimum_required(VERSION 3.8)
project(jwt-cpp-traits)
if(NOT TARGET jwt-cpp)
find_package(jwt-cpp CONFIG REQUIRED)
endif()
find_package(jsoncons CONFIG)
if(TARGET jsoncons)
add_executable(danielaparker-jsoncons danielaparker-jsoncons.cpp)
target_link_libraries(danielaparker-jsoncons jwt-cpp::jwt-cpp jsoncons)
endif()
include("../../cmake/private-find-boost-json.cmake")
if(TARGET boost_json)
add_executable(boost-json boost-json.cpp)
target_link_libraries(boost-json jwt-cpp::jwt-cpp boost_json)
endif()
find_package(nlohmann_json CONFIG)
if(TARGET nlohmann_json::nlohmann_json)
add_executable(nlohmann-json nlohmann-json.cpp)
target_link_libraries(nlohmann-json nlohmann_json::nlohmann_json jwt-cpp::jwt-cpp)
endif()
include("../../cmake/private-find-kazuho-picojson.cmake")
if(TARGET kazuho_picojson)
add_executable(kazuho-picojson kazuho-picojson.cpp)
target_link_libraries(kazuho-picojson jwt-cpp::jwt-cpp kazuho_picojson)
endif()
@@ -1,6 +0,0 @@
# Traits Examples
These example require upstream CMake installation to work. There are exceptions:
- For Boost.JSON headers must be located by custom CMake.
- For PicoJSON headers must be located by custom CMake.
@@ -1,52 +0,0 @@
#include "jwt-cpp/traits/boost-json/traits.h"
// #include <boost/json/src.hpp> // You may require this if you are not building it elsewhere
#include <iostream>
#include <sstream>
int main() {
using sec = std::chrono::seconds;
using min = std::chrono::minutes;
using traits = jwt::traits::boost_json;
using claim = jwt::basic_claim<traits>;
traits::value_type raw_value;
traits::parse(raw_value, R"##({"api":{"array":[1,2,3],"null":null}})##");
claim from_raw_json(raw_value);
claim::set_t list{"once", "twice"};
std::vector<int64_t> big_numbers{727663072ULL, 770979831ULL, 427239169ULL, 525936436ULL};
const auto time = jwt::date::clock::now();
const auto token = jwt::create<traits>()
.set_type("JWT")
.set_issuer("auth.mydomain.io")
.set_audience("mydomain.io")
.set_issued_at(time)
.set_not_before(time)
.set_expires_at(time + min{2} + sec{15})
.set_payload_claim("boolean", true)
.set_payload_claim("integer", 12345)
.set_payload_claim("precision", 12.3456789)
.set_payload_claim("strings", claim(list))
.set_payload_claim("array", claim{big_numbers.begin(), big_numbers.end()})
.set_payload_claim("object", from_raw_json)
.sign(jwt::algorithm::none{});
const auto decoded = jwt::decode<traits>(token);
for (auto& e : decoded.get_header_json())
std::cout << e.key() << " = " << e.value() << std::endl;
const auto array =
traits::as_array(decoded.get_payload_claim("object").to_json().as_object()["api"].as_object()["array"]);
std::cout << "payload /object/api/array = " << array << std::endl;
jwt::verify<traits>()
.allow_algorithm(jwt::algorithm::none{})
.with_issuer("auth.mydomain.io")
.with_audience("mydomain.io")
.with_claim("object", from_raw_json)
.verify(decoded);
return 0;
}
@@ -1,47 +0,0 @@
#include "jwt-cpp/traits/danielaparker-jsoncons/traits.h"
#include <iostream>
#include <sstream>
int main() {
using sec = std::chrono::seconds;
using min = std::chrono::minutes;
using traits = jwt::traits::danielaparker_jsoncons;
using claim = jwt::basic_claim<traits>;
claim from_raw_json;
std::istringstream iss{R"##({"api":{"array":[1,2,3],"null":null}})##"};
iss >> from_raw_json;
claim::set_t list{"once", "twice"};
std::vector<int64_t> big_numbers{727663072ULL, 770979831ULL, 427239169ULL, 525936436ULL};
const auto time = jwt::date::clock::now();
const auto token = jwt::create<traits>()
.set_type("JWT")
.set_issuer("auth.mydomain.io")
.set_audience("mydomain.io")
.set_issued_at(time)
.set_not_before(time)
.set_expires_at(time + min{2} + sec{15})
.set_payload_claim("boolean", true)
.set_payload_claim("integer", 12345)
.set_payload_claim("precision", 12.3456789)
.set_payload_claim("strings", list)
.set_payload_claim("array", {big_numbers.begin(), big_numbers.end()})
.set_payload_claim("object", from_raw_json)
.sign(jwt::algorithm::none{});
const auto decoded = jwt::decode<traits>(token);
const auto array = traits::as_array(decoded.get_payload_claim("object").to_json()["api"]["array"]);
std::cout << "payload /object/api/array = " << array << std::endl;
jwt::verify<traits>()
.allow_algorithm(jwt::algorithm::none{})
.with_issuer("auth.mydomain.io")
.with_audience("mydomain.io")
.with_claim("object", from_raw_json)
.verify(decoded);
return 0;
}
@@ -1,47 +0,0 @@
#include "jwt-cpp/traits/kazuho-picojson/traits.h"
#include <iostream>
#include <sstream>
int main() {
using sec = std::chrono::seconds;
using min = std::chrono::minutes;
using traits = jwt::traits::kazuho_picojson;
using claim = jwt::basic_claim<traits>;
claim from_raw_json;
std::istringstream iss{R"##({"api":{"array":[1,2,3],"null":null}})##"};
iss >> from_raw_json;
claim::set_t list{"once", "twice"};
std::vector<int64_t> big_numbers{727663072ULL, 770979831ULL, 427239169ULL, 525936436ULL};
const auto time = jwt::date::clock::now();
const auto token = jwt::create<traits>()
.set_type("JWT")
.set_issuer("auth.mydomain.io")
.set_audience("mydomain.io")
.set_issued_at(time)
.set_not_before(time)
.set_expires_at(time + min{2} + sec{15})
.set_payload_claim("boolean", picojson::value(true))
.set_payload_claim("integer", picojson::value(int64_t{12345}))
.set_payload_claim("precision", picojson::value(12.345))
.set_payload_claim("strings", claim(list))
.set_payload_claim("array", claim(big_numbers.begin(), big_numbers.end()))
.set_payload_claim("object", from_raw_json)
.sign(jwt::algorithm::none{});
const auto decoded = jwt::decode<traits>(token);
const auto api_array = decoded.get_payload_claim("object").to_json().get("api").get("array");
std::cout << "api array = " << api_array << std::endl;
jwt::verify<traits>()
.allow_algorithm(jwt::algorithm::none{})
.with_issuer("auth.mydomain.io")
.with_audience("mydomain.io")
.with_claim("object", from_raw_json)
.verify(decoded);
return 0;
}
@@ -1,47 +0,0 @@
#include "jwt-cpp/traits/nlohmann-json/traits.h"
#include <iostream>
#include <sstream>
int main() {
using sec = std::chrono::seconds;
using min = std::chrono::minutes;
using traits = jwt::traits::nlohmann_json;
using claim = jwt::basic_claim<traits>;
claim from_raw_json;
std::istringstream iss{R"##({"api":{"array":[1,2,3],"null":null}})##"};
iss >> from_raw_json;
claim::set_t list{"once", "twice"};
std::vector<int64_t> big_numbers{727663072ULL, 770979831ULL, 427239169ULL, 525936436ULL};
const auto time = jwt::date::clock::now();
const auto token = jwt::create<traits>()
.set_type("JWT")
.set_issuer("auth.mydomain.io")
.set_audience("mydomain.io")
.set_issued_at(time)
.set_not_before(time)
.set_expires_at(time + min{2} + sec{15})
.set_payload_claim("boolean", true)
.set_payload_claim("integer", 12345)
.set_payload_claim("precision", 12.3456789)
.set_payload_claim("strings", list)
.set_payload_claim("array", {big_numbers.begin(), big_numbers.end()})
.set_payload_claim("object", from_raw_json)
.sign(jwt::algorithm::none{});
const auto decoded = jwt::decode<traits>(token);
const auto array = traits::as_array(decoded.get_payload_claim("object").to_json()["api"]["array"]);
std::cout << "payload /object/api/array = " << array << std::endl;
jwt::verify<traits>()
.allow_algorithm(jwt::algorithm::none{})
.with_issuer("auth.mydomain.io")
.with_audience("mydomain.io")
.with_claim("object", from_raw_json)
.verify(decoded);
return 0;
}
@@ -1,270 +0,0 @@
#ifndef JWT_CPP_BASE_H
#define JWT_CPP_BASE_H
#include <algorithm>
#include <array>
#include <cstdint>
#include <stdexcept>
#include <string>
#include <vector>
#ifdef __has_cpp_attribute
#if __has_cpp_attribute(fallthrough)
#define JWT_FALLTHROUGH [[fallthrough]]
#endif
#endif
#ifndef JWT_FALLTHROUGH
#define JWT_FALLTHROUGH
#endif
namespace jwt {
/**
* \brief character maps when encoding and decoding
*/
namespace alphabet {
/**
* \brief valid list of character when working with [Base64](https://datatracker.ietf.org/doc/html/rfc4648#section-4)
*
* As directed in [X.509 Parameter](https://datatracker.ietf.org/doc/html/rfc7517#section-4.7) certificate chains are
* base64-encoded as per [Section 4 of RFC4648](https://datatracker.ietf.org/doc/html/rfc4648#section-4)
*/
struct base64 {
static const std::array<char, 64>& data() {
static constexpr std::array<char, 64> data{
{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}};
return data;
}
static const std::string& fill() {
static const std::string fill{"="};
return fill;
}
};
/**
* \brief valid list of character when working with [Base64URL](https://tools.ietf.org/html/rfc4648#section-5)
*
* As directed by [RFC 7519 Terminology](https://datatracker.ietf.org/doc/html/rfc7519#section-2) set the definition of Base64URL
* encoding as that in [RFC 7515](https://datatracker.ietf.org/doc/html/rfc7515#section-2) that states:
*
* > Base64 encoding using the URL- and filename-safe character set defined in
* > [Section 5 of RFC 4648 RFC4648](https://tools.ietf.org/html/rfc4648#section-5), with all trailing '=' characters omitted
*/
struct base64url {
static const std::array<char, 64>& data() {
static constexpr std::array<char, 64> data{
{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_'}};
return data;
}
static const std::string& fill() {
static const std::string fill{"%3d"};
return fill;
}
};
namespace helper {
/**
* @brief A General purpose base64url alphabet respecting the
* [URI Case Normalization](https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2.1)
*
* This is useful in situations outside of JWT encoding/decoding and is provided as a helper
*/
struct base64url_percent_encoding {
static const std::array<char, 64>& data() {
static constexpr std::array<char, 64> data{
{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_'}};
return data;
}
static const std::vector<std::string>& fill() {
static const std::vector<std::string> fill{"%3D", "%3d"};
return fill;
}
};
} // namespace helper
inline uint32_t index(const std::array<char, 64>& alphabet, char symbol) {
auto itr = std::find_if(alphabet.cbegin(), alphabet.cend(), [symbol](char c) { return c == symbol; });
if (itr == alphabet.cend()) { throw std::runtime_error("Invalid input: not within alphabet"); }
return std::distance(alphabet.cbegin(), itr);
}
} // namespace alphabet
/**
* \brief A collection of fellable functions for working with base64 and base64url
*/
namespace base {
namespace details {
struct padding {
size_t count = 0;
size_t length = 0;
padding() = default;
padding(size_t count, size_t length) : count(count), length(length) {}
padding operator+(const padding& p) { return padding(count + p.count, length + p.length); }
friend bool operator==(const padding& lhs, const padding& rhs) {
return lhs.count == rhs.count && lhs.length == rhs.length;
}
};
inline padding count_padding(const std::string& base, const std::vector<std::string>& fills) {
for (const auto& fill : fills) {
if (base.size() < fill.size()) continue;
// Does the end of the input exactly match the fill pattern?
if (base.substr(base.size() - fill.size()) == fill) {
return padding{1, fill.length()} +
count_padding(base.substr(0, base.size() - fill.size()), fills);
}
}
return {};
}
inline std::string encode(const std::string& bin, const std::array<char, 64>& alphabet,
const std::string& fill) {
size_t size = bin.size();
std::string res;
// clear incomplete bytes
size_t fast_size = size - size % 3;
for (size_t i = 0; i < fast_size;) {
uint32_t octet_a = static_cast<unsigned char>(bin[i++]);
uint32_t octet_b = static_cast<unsigned char>(bin[i++]);
uint32_t octet_c = static_cast<unsigned char>(bin[i++]);
uint32_t triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;
res += alphabet[(triple >> 3 * 6) & 0x3F];
res += alphabet[(triple >> 2 * 6) & 0x3F];
res += alphabet[(triple >> 1 * 6) & 0x3F];
res += alphabet[(triple >> 0 * 6) & 0x3F];
}
if (fast_size == size) return res;
size_t mod = size % 3;
uint32_t octet_a = fast_size < size ? static_cast<unsigned char>(bin[fast_size++]) : 0;
uint32_t octet_b = fast_size < size ? static_cast<unsigned char>(bin[fast_size++]) : 0;
uint32_t octet_c = fast_size < size ? static_cast<unsigned char>(bin[fast_size++]) : 0;
uint32_t triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;
switch (mod) {
case 1:
res += alphabet[(triple >> 3 * 6) & 0x3F];
res += alphabet[(triple >> 2 * 6) & 0x3F];
res += fill;
res += fill;
break;
case 2:
res += alphabet[(triple >> 3 * 6) & 0x3F];
res += alphabet[(triple >> 2 * 6) & 0x3F];
res += alphabet[(triple >> 1 * 6) & 0x3F];
res += fill;
break;
default: break;
}
return res;
}
inline std::string decode(const std::string& base, const std::array<char, 64>& alphabet,
const std::vector<std::string>& fill) {
const auto pad = count_padding(base, fill);
if (pad.count > 2) throw std::runtime_error("Invalid input: too much fill");
const size_t size = base.size() - pad.length;
if ((size + pad.count) % 4 != 0) throw std::runtime_error("Invalid input: incorrect total size");
size_t out_size = size / 4 * 3;
std::string res;
res.reserve(out_size);
auto get_sextet = [&](size_t offset) { return alphabet::index(alphabet, base[offset]); };
size_t fast_size = size - size % 4;
for (size_t i = 0; i < fast_size;) {
uint32_t sextet_a = get_sextet(i++);
uint32_t sextet_b = get_sextet(i++);
uint32_t sextet_c = get_sextet(i++);
uint32_t sextet_d = get_sextet(i++);
uint32_t triple =
(sextet_a << 3 * 6) + (sextet_b << 2 * 6) + (sextet_c << 1 * 6) + (sextet_d << 0 * 6);
res += static_cast<char>((triple >> 2 * 8) & 0xFFU);
res += static_cast<char>((triple >> 1 * 8) & 0xFFU);
res += static_cast<char>((triple >> 0 * 8) & 0xFFU);
}
if (pad.count == 0) return res;
uint32_t triple = (get_sextet(fast_size) << 3 * 6) + (get_sextet(fast_size + 1) << 2 * 6);
switch (pad.count) {
case 1:
triple |= (get_sextet(fast_size + 2) << 1 * 6);
res += static_cast<char>((triple >> 2 * 8) & 0xFFU);
res += static_cast<char>((triple >> 1 * 8) & 0xFFU);
break;
case 2: res += static_cast<char>((triple >> 2 * 8) & 0xFFU); break;
default: break;
}
return res;
}
inline std::string decode(const std::string& base, const std::array<char, 64>& alphabet,
const std::string& fill) {
return decode(base, alphabet, std::vector<std::string>{fill});
}
inline std::string pad(const std::string& base, const std::string& fill) {
std::string padding;
switch (base.size() % 4) {
case 1: padding += fill; JWT_FALLTHROUGH;
case 2: padding += fill; JWT_FALLTHROUGH;
case 3: padding += fill; JWT_FALLTHROUGH;
default: break;
}
return base + padding;
}
inline std::string trim(const std::string& base, const std::string& fill) {
auto pos = base.find(fill);
return base.substr(0, pos);
}
} // namespace details
template<typename T>
std::string encode(const std::string& bin) {
return details::encode(bin, T::data(), T::fill());
}
template<typename T>
std::string decode(const std::string& base) {
return details::decode(base, T::data(), T::fill());
}
template<typename T>
std::string pad(const std::string& base) {
return details::pad(base, T::fill());
}
template<typename T>
std::string trim(const std::string& base) {
return details::trim(base, T::fill());
}
} // namespace base
} // namespace jwt
#endif
File diff suppressed because it is too large Load Diff
@@ -1,88 +0,0 @@
#ifndef JWT_CPP_BOOST_JSON_DEFAULTS_H
#define JWT_CPP_BOOST_JSON_DEFAULTS_H
#ifndef JWT_DISABLE_PICOJSON
#define JWT_DISABLE_PICOJSON
#endif
#include "traits.h"
namespace jwt {
/**
* \brief a class to store a generic [Boost.JSON](https://github.com/boostorg/json) value as claim
*
* This type is the specialization of the \ref basic_claim class which
* uses the standard template types.
*/
using claim = basic_claim<traits::boost_json>;
/**
* Create a verifier using the default clock
* \return verifier instance
*/
inline verifier<default_clock, traits::boost_json> verify() {
return verify<default_clock, traits::boost_json>(default_clock{});
}
/**
* Return a builder instance to create a new token
*/
inline builder<traits::boost_json> create() { return builder<traits::boost_json>(); }
#ifndef JWT_DISABLE_BASE64
/**
* Decode a token
* \param token Token to decode
* \return Decoded token
* \throw std::invalid_argument Token is not in correct format
* \throw std::runtime_error Base64 decoding failed or invalid json
*/
inline decoded_jwt<traits::boost_json> decode(const std::string& token) {
return decoded_jwt<traits::boost_json>(token);
}
#endif
/**
* Decode a token
* \tparam Decode is callabled, taking a string_type and returns a string_type.
* It should ensure the padding of the input and then base64url decode and
* return the results.
* \param token Token to decode
* \param decode The token to parse
* \return Decoded token
* \throw std::invalid_argument Token is not in correct format
* \throw std::runtime_error Base64 decoding failed or invalid json
*/
template<typename Decode>
decoded_jwt<traits::boost_json> decode(const std::string& token, Decode decode) {
return decoded_jwt<traits::boost_json>(token, decode);
}
/**
* Parse a jwk
* \param token JWK Token to parse
* \return Parsed JWK
* \throw std::runtime_error Token is not in correct format
*/
inline jwk<traits::boost_json> parse_jwk(const traits::boost_json::string_type& token) {
return jwk<traits::boost_json>(token);
}
/**
* Parse a jwks
* \param token JWKs Token to parse
* \return Parsed JWKs
* \throw std::runtime_error Token is not in correct format
*/
inline jwks<traits::boost_json> parse_jwks(const traits::boost_json::string_type& token) {
return jwks<traits::boost_json>(token);
}
/**
* This type is the specialization of the \ref verify_ops::verify_context class which
* uses the standard template types.
*/
using verify_context = verify_ops::verify_context<traits::boost_json>;
} // namespace jwt
#endif // JWT_CPP_BOOST_JSON_DEFAULTS_H
@@ -1,80 +0,0 @@
#ifndef JWT_CPP_BOOSTJSON_TRAITS_H
#define JWT_CPP_BOOSTJSON_TRAITS_H
#define JWT_DISABLE_PICOJSON
#include "jwt-cpp/jwt.h"
#include <boost/json.hpp>
// if not boost JSON standalone then error...
namespace jwt {
namespace traits {
namespace json = boost::json;
struct boost_json {
using value_type = json::value;
using object_type = json::object;
using array_type = json::array;
using string_type = std::string;
using number_type = double;
using integer_type = std::int64_t;
using boolean_type = bool;
static jwt::json::type get_type(const value_type& val) {
using jwt::json::type;
if (val.kind() == json::kind::bool_) return type::boolean;
if (val.kind() == json::kind::int64) return type::integer;
if (val.kind() == json::kind::uint64) // boost internally tracks two types of integers
return type::integer;
if (val.kind() == json::kind::double_) return type::number;
if (val.kind() == json::kind::string) return type::string;
if (val.kind() == json::kind::array) return type::array;
if (val.kind() == json::kind::object) return type::object;
throw std::logic_error("invalid type");
}
static object_type as_object(const value_type& val) {
if (val.kind() != json::kind::object) throw std::bad_cast();
return val.get_object();
}
static array_type as_array(const value_type& val) {
if (val.kind() != json::kind::array) throw std::bad_cast();
return val.get_array();
}
static string_type as_string(const value_type& val) {
if (val.kind() != json::kind::string) throw std::bad_cast();
return string_type{val.get_string()};
}
static integer_type as_integer(const value_type& val) {
switch (val.kind()) {
case json::kind::int64: return val.get_int64();
case json::kind::uint64: return static_cast<int64_t>(val.get_uint64());
default: throw std::bad_cast();
}
}
static boolean_type as_boolean(const value_type& val) {
if (val.kind() != json::kind::bool_) throw std::bad_cast();
return val.get_bool();
}
static number_type as_number(const value_type& val) {
if (val.kind() != json::kind::double_) throw std::bad_cast();
return val.get_double();
}
static bool parse(value_type& val, string_type str) {
val = json::parse(str);
return true;
}
static std::string serialize(const value_type& val) { return json::serialize(val); }
};
} // namespace traits
} // namespace jwt
#endif // JWT_CPP_BOOSTJSON_TRAITS_H
@@ -1,88 +0,0 @@
#ifndef JWT_CPP_DANIELAPARKER_JSONCONS_DEFAULTS_H
#define JWT_CPP_DANIELAPARKER_JSONCONS_DEFAULTS_H
#ifndef JWT_DISABLE_PICOJSON
#define JWT_DISABLE_PICOJSON
#endif
#include "traits.h"
namespace jwt {
/**
* \brief a class to store a generic [jsoncons](https://github.com/danielaparker/jsoncons) value as claim
*
* This type is the specialization of the \ref basic_claim class which
* uses the standard template types.
*/
using claim = basic_claim<traits::danielaparker_jsoncons>;
/**
* Create a verifier using the default clock
* \return verifier instance
*/
inline verifier<default_clock, traits::danielaparker_jsoncons> verify() {
return verify<default_clock, traits::danielaparker_jsoncons>(default_clock{});
}
/**
* Return a builder instance to create a new token
*/
inline builder<traits::danielaparker_jsoncons> create() { return builder<traits::danielaparker_jsoncons>(); }
#ifndef JWT_DISABLE_BASE64
/**
* Decode a token
* \param token Token to decode
* \return Decoded token
* \throw std::invalid_argument Token is not in correct format
* \throw std::runtime_error Base64 decoding failed or invalid json
*/
inline decoded_jwt<traits::danielaparker_jsoncons> decode(const std::string& token) {
return decoded_jwt<traits::danielaparker_jsoncons>(token);
}
#endif
/**
* Decode a token
* \tparam Decode is callabled, taking a string_type and returns a string_type.
* It should ensure the padding of the input and then base64url decode and
* return the results.
* \param token Token to decode
* \param decode The token to parse
* \return Decoded token
* \throw std::invalid_argument Token is not in correct format
* \throw std::runtime_error Base64 decoding failed or invalid json
*/
template<typename Decode>
decoded_jwt<traits::danielaparker_jsoncons> decode(const std::string& token, Decode decode) {
return decoded_jwt<traits::danielaparker_jsoncons>(token, decode);
}
/**
* Parse a jwk
* \param token JWK Token to parse
* \return Parsed JWK
* \throw std::runtime_error Token is not in correct format
*/
inline jwk<traits::danielaparker_jsoncons> parse_jwk(const traits::danielaparker_jsoncons::string_type& token) {
return jwk<traits::danielaparker_jsoncons>(token);
}
/**
* Parse a jwks
* \param token JWKs Token to parse
* \return Parsed JWKs
* \throw std::runtime_error Token is not in correct format
*/
inline jwks<traits::danielaparker_jsoncons> parse_jwks(const traits::danielaparker_jsoncons::string_type& token) {
return jwks<traits::danielaparker_jsoncons>(token);
}
/**
* This type is the specialization of the \ref verify_ops::verify_context class which
* uses the standard template types.
*/
using verify_context = verify_ops::verify_context<traits::danielaparker_jsoncons>;
} // namespace jwt
#endif // JWT_CPP_DANIELAPARKER_JSONCONS_DEFAULTS_H
@@ -1,123 +0,0 @@
#define JWT_DISABLE_PICOJSON
#define JSONCONS_NO_DEPRECATED
#include "jwt-cpp/jwt.h"
#include "jsoncons/json.hpp"
#include <sstream>
namespace jwt {
namespace traits {
struct danielaparker_jsoncons {
// Needs at least https://github.com/danielaparker/jsoncons/commit/28c56b90ec7337f98a5b8942574590111a5e5831
static_assert(jsoncons::version().minor >= 167, "A higher version of jsoncons is required!");
using json = jsoncons::json;
using value_type = json;
struct object_type : json::object {
// Add missing C++11 member types
// https://github.com/danielaparker/jsoncons/commit/1b1ceeb572f9a2db6d37cff47ac78a4f14e072e2#commitcomment-45391411
using value_type = key_value_type; // Enable optional jwt-cpp methods
using mapped_type = key_value_type::value_type;
using size_type = size_t; // for implementing count
object_type() = default;
object_type(const object_type&) = default;
explicit object_type(const json::object& o) : json::object(o) {}
object_type(object_type&&) = default;
explicit object_type(json::object&& o) : json::object(o) {}
~object_type() = default;
object_type& operator=(const object_type& o) = default;
object_type& operator=(object_type&& o) noexcept = default;
// Add missing C++11 subscription operator
mapped_type& operator[](const key_type& key) {
// https://github.com/microsoft/STL/blob/2914b4301c59dc7ffc09d16ac6f7979fde2b7f2c/stl/inc/map#L325
return try_emplace(key).first->value();
}
// Add missing C++11 element access
const mapped_type& at(const key_type& key) const {
auto target = find(key);
if (target != end()) return target->value();
throw std::out_of_range("invalid key");
}
// Add missing C++11 lookup method
size_type count(const key_type& key) const {
struct compare {
bool operator()(const value_type& val, const key_type& key) const { return val.key() < key; }
bool operator()(const key_type& key, const value_type& val) const { return key < val.key(); }
};
// https://en.cppreference.com/w/cpp/algorithm/binary_search#Complexity
if (std::binary_search(this->begin(), this->end(), key, compare{})) return 1;
return 0;
}
};
using array_type = json::array;
using string_type = std::string; // current limitation of traits implementation
using number_type = double;
using integer_type = int64_t;
using boolean_type = bool;
static jwt::json::type get_type(const json& val) {
using jwt::json::type;
if (val.type() == jsoncons::json_type::bool_value) return type::boolean;
if (val.type() == jsoncons::json_type::int64_value) return type::integer;
if (val.type() == jsoncons::json_type::uint64_value) return type::integer;
if (val.type() == jsoncons::json_type::half_value) return type::number;
if (val.type() == jsoncons::json_type::double_value) return type::number;
if (val.type() == jsoncons::json_type::string_value) return type::string;
if (val.type() == jsoncons::json_type::array_value) return type::array;
if (val.type() == jsoncons::json_type::object_value) return type::object;
throw std::logic_error("invalid type");
}
static object_type as_object(const json& val) {
if (val.type() != jsoncons::json_type::object_value) throw std::bad_cast();
return object_type(val.object_value());
}
static array_type as_array(const json& val) {
if (val.type() != jsoncons::json_type::array_value) throw std::bad_cast();
return val.array_value();
}
static string_type as_string(const json& val) {
if (val.type() != jsoncons::json_type::string_value) throw std::bad_cast();
return val.as_string();
}
static number_type as_number(const json& val) {
if (get_type(val) != jwt::json::type::number) throw std::bad_cast();
return val.as_double();
}
static integer_type as_integer(const json& val) {
if (get_type(val) != jwt::json::type::integer) throw std::bad_cast();
return val.as<integer_type>();
}
static boolean_type as_boolean(const json& val) {
if (val.type() != jsoncons::json_type::bool_value) throw std::bad_cast();
return val.as_bool();
}
static bool parse(json& val, const std::string& str) {
val = json::parse(str);
return true;
}
static std::string serialize(const json& val) {
std::ostringstream os;
os << jsoncons::print(val);
return os.str();
}
};
} // namespace traits
} // namespace jwt
@@ -1,90 +0,0 @@
#ifndef JWT_CPP_{{traits_name_upper}}_DEFAULTS_H
#define JWT_CPP_{{traits_name_upper}}_DEFAULTS_H
{{#disable_default_traits}}
#ifndef JWT_DISABLE_PICOJSON
#define JWT_DISABLE_PICOJSON
#endif
{{/disable_default_traits}}
#include "traits.h"
namespace jwt {
/**
* \brief a class to store a generic [{{library_name}}]({{{library_url}}}) value as claim
*
* This type is the specialization of the \ref basic_claim class which
* uses the standard template types.
*/
using claim = basic_claim<traits::{{traits_name}}>;
/**
* Create a verifier using the default clock
* \return verifier instance
*/
inline verifier<default_clock, traits::{{traits_name}}> verify() {
return verify<default_clock, traits::{{traits_name}}>(default_clock{});
}
/**
* Return a builder instance to create a new token
*/
inline builder<traits::{{traits_name}}> create() { return builder<traits::{{traits_name}}>(); }
#ifndef JWT_DISABLE_BASE64
/**
* Decode a token
* \param token Token to decode
* \return Decoded token
* \throw std::invalid_argument Token is not in correct format
* \throw std::runtime_error Base64 decoding failed or invalid json
*/
inline decoded_jwt<traits::{{traits_name}}> decode(const std::string& token) {
return decoded_jwt<traits::{{traits_name}}>(token);
}
#endif
/**
* Decode a token
* \tparam Decode is callabled, taking a string_type and returns a string_type.
* It should ensure the padding of the input and then base64url decode and
* return the results.
* \param token Token to decode
* \param decode The token to parse
* \return Decoded token
* \throw std::invalid_argument Token is not in correct format
* \throw std::runtime_error Base64 decoding failed or invalid json
*/
template<typename Decode>
decoded_jwt<traits::{{traits_name}}> decode(const std::string& token, Decode decode) {
return decoded_jwt<traits::{{traits_name}}>(token, decode);
}
/**
* Parse a jwk
* \param token JWK Token to parse
* \return Parsed JWK
* \throw std::runtime_error Token is not in correct format
*/
inline jwk<traits::{{traits_name}}> parse_jwk(const traits::{{traits_name}}::string_type& token) {
return jwk<traits::{{traits_name}}>(token);
}
/**
* Parse a jwks
* \param token JWKs Token to parse
* \return Parsed JWKs
* \throw std::runtime_error Token is not in correct format
*/
inline jwks<traits::{{traits_name}}> parse_jwks(const traits::{{traits_name}}::string_type& token) {
return jwks<traits::{{traits_name}}>(token);
}
/**
* This type is the specialization of the \ref verify_ops::verify_context class which
* uses the standard template types.
*/
using verify_context = verify_ops::verify_context<traits::{{traits_name}}>;
} // namespace jwt
#endif // JWT_CPP_{{traits_name_upper}}_DEFAULTS_H
@@ -1,84 +0,0 @@
#ifndef JWT_CPP_KAZUHO_PICOJSON_DEFAULTS_H
#define JWT_CPP_KAZUHO_PICOJSON_DEFAULTS_H
#include "traits.h"
namespace jwt {
/**
* \brief a class to store a generic [picojson](https://github.com/kazuho/picojson) value as claim
*
* This type is the specialization of the \ref basic_claim class which
* uses the standard template types.
*/
using claim = basic_claim<traits::kazuho_picojson>;
/**
* Create a verifier using the default clock
* \return verifier instance
*/
inline verifier<default_clock, traits::kazuho_picojson> verify() {
return verify<default_clock, traits::kazuho_picojson>(default_clock{});
}
/**
* Return a builder instance to create a new token
*/
inline builder<traits::kazuho_picojson> create() { return builder<traits::kazuho_picojson>(); }
#ifndef JWT_DISABLE_BASE64
/**
* Decode a token
* \param token Token to decode
* \return Decoded token
* \throw std::invalid_argument Token is not in correct format
* \throw std::runtime_error Base64 decoding failed or invalid json
*/
inline decoded_jwt<traits::kazuho_picojson> decode(const std::string& token) {
return decoded_jwt<traits::kazuho_picojson>(token);
}
#endif
/**
* Decode a token
* \tparam Decode is callabled, taking a string_type and returns a string_type.
* It should ensure the padding of the input and then base64url decode and
* return the results.
* \param token Token to decode
* \param decode The token to parse
* \return Decoded token
* \throw std::invalid_argument Token is not in correct format
* \throw std::runtime_error Base64 decoding failed or invalid json
*/
template<typename Decode>
decoded_jwt<traits::kazuho_picojson> decode(const std::string& token, Decode decode) {
return decoded_jwt<traits::kazuho_picojson>(token, decode);
}
/**
* Parse a jwk
* \param token JWK Token to parse
* \return Parsed JWK
* \throw std::runtime_error Token is not in correct format
*/
inline jwk<traits::kazuho_picojson> parse_jwk(const traits::kazuho_picojson::string_type& token) {
return jwk<traits::kazuho_picojson>(token);
}
/**
* Parse a jwks
* \param token JWKs Token to parse
* \return Parsed JWKs
* \throw std::runtime_error Token is not in correct format
*/
inline jwks<traits::kazuho_picojson> parse_jwks(const traits::kazuho_picojson::string_type& token) {
return jwks<traits::kazuho_picojson>(token);
}
/**
* This type is the specialization of the \ref verify_ops::verify_context class which
* uses the standard template types.
*/
using verify_context = verify_ops::verify_context<traits::kazuho_picojson>;
} // namespace jwt
#endif // JWT_CPP_KAZUHO_PICOJSON_DEFAULTS_H
@@ -1,76 +0,0 @@
#ifndef JWT_CPP_PICOJSON_TRAITS_H
#define JWT_CPP_PICOJSON_TRAITS_H
#ifndef PICOJSON_USE_INT64
#define PICOJSON_USE_INT64
#endif
#include "picojson/picojson.h"
#ifndef JWT_DISABLE_PICOJSON
#define JWT_DISABLE_PICOJSON
#endif
#include "jwt-cpp/jwt.h"
namespace jwt {
namespace traits {
struct kazuho_picojson {
using value_type = picojson::value;
using object_type = picojson::object;
using array_type = picojson::array;
using string_type = std::string;
using number_type = double;
using integer_type = int64_t;
using boolean_type = bool;
static json::type get_type(const picojson::value& val) {
using json::type;
if (val.is<bool>()) return type::boolean;
if (val.is<int64_t>()) return type::integer;
if (val.is<double>()) return type::number;
if (val.is<std::string>()) return type::string;
if (val.is<picojson::array>()) return type::array;
if (val.is<picojson::object>()) return type::object;
throw std::logic_error("invalid type");
}
static picojson::object as_object(const picojson::value& val) {
if (!val.is<picojson::object>()) throw std::bad_cast();
return val.get<picojson::object>();
}
static std::string as_string(const picojson::value& val) {
if (!val.is<std::string>()) throw std::bad_cast();
return val.get<std::string>();
}
static picojson::array as_array(const picojson::value& val) {
if (!val.is<picojson::array>()) throw std::bad_cast();
return val.get<picojson::array>();
}
static int64_t as_integer(const picojson::value& val) {
if (!val.is<int64_t>()) throw std::bad_cast();
return val.get<int64_t>();
}
static bool as_boolean(const picojson::value& val) {
if (!val.is<bool>()) throw std::bad_cast();
return val.get<bool>();
}
static double as_number(const picojson::value& val) {
if (!val.is<double>()) throw std::bad_cast();
return val.get<double>();
}
static bool parse(picojson::value& val, const std::string& str) {
return picojson::parse(val, str).empty();
}
static std::string serialize(const picojson::value& val) { return val.serialize(); }
};
} // namespace traits
} // namespace jwt
#endif
@@ -1,88 +0,0 @@
#ifndef JWT_CPP_NLOHMANN_JSON_DEFAULTS_H
#define JWT_CPP_NLOHMANN_JSON_DEFAULTS_H
#ifndef JWT_DISABLE_PICOJSON
#define JWT_DISABLE_PICOJSON
#endif
#include "traits.h"
namespace jwt {
/**
* \brief a class to store a generic [JSON for Modern C++](https://github.com/nlohmann/json) value as claim
*
* This type is the specialization of the \ref basic_claim class which
* uses the standard template types.
*/
using claim = basic_claim<traits::nlohmann_json>;
/**
* Create a verifier using the default clock
* \return verifier instance
*/
inline verifier<default_clock, traits::nlohmann_json> verify() {
return verify<default_clock, traits::nlohmann_json>(default_clock{});
}
/**
* Return a builder instance to create a new token
*/
inline builder<traits::nlohmann_json> create() { return builder<traits::nlohmann_json>(); }
#ifndef JWT_DISABLE_BASE64
/**
* Decode a token
* \param token Token to decode
* \return Decoded token
* \throw std::invalid_argument Token is not in correct format
* \throw std::runtime_error Base64 decoding failed or invalid json
*/
inline decoded_jwt<traits::nlohmann_json> decode(const std::string& token) {
return decoded_jwt<traits::nlohmann_json>(token);
}
#endif
/**
* Decode a token
* \tparam Decode is callabled, taking a string_type and returns a string_type.
* It should ensure the padding of the input and then base64url decode and
* return the results.
* \param token Token to decode
* \param decode The token to parse
* \return Decoded token
* \throw std::invalid_argument Token is not in correct format
* \throw std::runtime_error Base64 decoding failed or invalid json
*/
template<typename Decode>
decoded_jwt<traits::nlohmann_json> decode(const std::string& token, Decode decode) {
return decoded_jwt<traits::nlohmann_json>(token, decode);
}
/**
* Parse a jwk
* \param token JWK Token to parse
* \return Parsed JWK
* \throw std::runtime_error Token is not in correct format
*/
inline jwk<traits::nlohmann_json> parse_jwk(const traits::nlohmann_json::string_type& token) {
return jwk<traits::nlohmann_json>(token);
}
/**
* Parse a jwks
* \param token JWKs Token to parse
* \return Parsed JWKs
* \throw std::runtime_error Token is not in correct format
*/
inline jwks<traits::nlohmann_json> parse_jwks(const traits::nlohmann_json::string_type& token) {
return jwks<traits::nlohmann_json>(token);
}
/**
* This type is the specialization of the \ref verify_ops::verify_context class which
* uses the standard template types.
*/
using verify_context = verify_ops::verify_context<traits::nlohmann_json>;
} // namespace jwt
#endif // JWT_CPP_NLOHMANN_JSON_DEFAULTS_H
@@ -1,77 +0,0 @@
#ifndef JWT_CPP_NLOHMANN_JSON_TRAITS_H
#define JWT_CPP_NLOHMANN_JSON_TRAITS_H
#include "jwt-cpp/jwt.h"
#include "nlohmann/json.hpp"
namespace jwt {
namespace traits {
struct nlohmann_json {
using json = nlohmann::json;
using value_type = json;
using object_type = json::object_t;
using array_type = json::array_t;
using string_type = std::string; // current limitation of traits implementation
using number_type = json::number_float_t;
using integer_type = json::number_integer_t;
using boolean_type = json::boolean_t;
static jwt::json::type get_type(const json& val) {
using jwt::json::type;
if (val.type() == json::value_t::boolean) return type::boolean;
// nlohmann internally tracks two types of integers
if (val.type() == json::value_t::number_integer) return type::integer;
if (val.type() == json::value_t::number_unsigned) return type::integer;
if (val.type() == json::value_t::number_float) return type::number;
if (val.type() == json::value_t::string) return type::string;
if (val.type() == json::value_t::array) return type::array;
if (val.type() == json::value_t::object) return type::object;
throw std::logic_error("invalid type");
}
static json::object_t as_object(const json& val) {
if (val.type() != json::value_t::object) throw std::bad_cast();
return val.get<json::object_t>();
}
static std::string as_string(const json& val) {
if (val.type() != json::value_t::string) throw std::bad_cast();
return val.get<std::string>();
}
static json::array_t as_array(const json& val) {
if (val.type() != json::value_t::array) throw std::bad_cast();
return val.get<json::array_t>();
}
static int64_t as_integer(const json& val) {
switch (val.type()) {
case json::value_t::number_integer:
case json::value_t::number_unsigned: return val.get<int64_t>();
default: throw std::bad_cast();
}
}
static bool as_boolean(const json& val) {
if (val.type() != json::value_t::boolean) throw std::bad_cast();
return val.get<bool>();
}
static double as_number(const json& val) {
if (val.type() != json::value_t::number_float) throw std::bad_cast();
return val.get<double>();
}
static bool parse(json& val, std::string str) {
val = json::parse(str.begin(), str.end());
return true;
}
static std::string serialize(const json& val) { return val.dump(); }
};
} // namespace traits
} // namespace jwt
#endif
File diff suppressed because it is too large Load Diff
@@ -1,29 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<package>
<metadata>
<id>jwt-cpp</id>
<version>0.7.0</version>
<authors>Thalhammer; prince-chrismc</authors>
<owners>Thalhammer; prince-chrismc</owners>
<projectUrl>https://github.com/Thalhammer/jwt-cpp</projectUrl>
<description>JWT++ is a header only library for creating and validating JSON Web Tokens in C++11. This library supports all the algorithms defined by the JWT specifications, and the modular design allows to easily add additional algorithms without any problems. In the name of flexibility and extensibility, jwt-cpp supports OpenSSL, LibreSSL, and wolfSSL. And there is no hard dependency on a JSON library.
</description>
<releaseNotes>Supporting OpenSSL 3.0.0, WolfSSL, Hunter CMake, Boost.JSON, JWKs, ES256K.</releaseNotes>
<license type="expression">MIT</license>
<copyright>Copyright (c) 2018 Dominik Thalhammer</copyright>
<title>JWT++: JSON Web Tokens in C++11</title>
<summary>JWT++; a header only library for creating and validating JSON Web Tokens in C++11.</summary>
<tags>JWT, json, web, token, C++, header-only</tags>
<dependencies>
<group targetFramework="native0.0">
<dependency id="PicoJSON" version="1.3.0" />
<dependency id="openssl-vc141-static-x86_64" version="1.1.0" />
</group>
</dependencies>
</metadata>
<files>
<file src="..\include\jwt-cpp\**" target="\lib\native\include\jwt-cpp\" />
<file src="jwt-cpp.targets" target="\build\native\" />
<file src="..\README.md" target="docs\" />
</files>
</package>
@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" >
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)..\..\lib\native\include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
</Project>
-110
View File
@@ -1,110 +0,0 @@
#include "jwt-cpp/base.h"
#include <gtest/gtest.h>
TEST(BaseTest, Base64Index) {
ASSERT_EQ(0, jwt::alphabet::index(jwt::alphabet::base64::data(), 'A'));
ASSERT_EQ(32, jwt::alphabet::index(jwt::alphabet::base64::data(), 'g'));
ASSERT_EQ(62, jwt::alphabet::index(jwt::alphabet::base64::data(), '+'));
}
TEST(BaseTest, Base64URLIndex) {
ASSERT_EQ(0, jwt::alphabet::index(jwt::alphabet::base64url::data(), 'A'));
ASSERT_EQ(32, jwt::alphabet::index(jwt::alphabet::base64url::data(), 'g'));
ASSERT_EQ(62, jwt::alphabet::index(jwt::alphabet::base64url::data(), '-'));
}
TEST(BaseTest, BaseDetailsCountPadding) {
using jwt::base::details::padding;
ASSERT_EQ(padding{}, jwt::base::details::count_padding("ABC", {"~"}));
ASSERT_EQ((padding{3, 3}), jwt::base::details::count_padding("ABC~~~", {"~"}));
ASSERT_EQ((padding{5, 5}), jwt::base::details::count_padding("ABC~~~~~", {"~"}));
ASSERT_EQ(padding{}, jwt::base::details::count_padding("ABC", {"~", "!"}));
ASSERT_EQ((padding{1, 1}), jwt::base::details::count_padding("ABC!", {"~", "!"}));
ASSERT_EQ((padding{1, 1}), jwt::base::details::count_padding("ABC~", {"~", "!"}));
ASSERT_EQ((padding{3, 3}), jwt::base::details::count_padding("ABC~~!", {"~", "!"}));
ASSERT_EQ((padding{3, 3}), jwt::base::details::count_padding("ABC!~~", {"~", "!"}));
ASSERT_EQ((padding{5, 5}), jwt::base::details::count_padding("ABC~~!~~", {"~", "!"}));
ASSERT_EQ((padding{2, 6}), jwt::base::details::count_padding("MTIzNA%3d%3d", {"%3d", "%3D"}));
ASSERT_EQ((padding{2, 6}), jwt::base::details::count_padding("MTIzNA%3d%3D", {"%3d", "%3D"}));
ASSERT_EQ((padding{2, 6}), jwt::base::details::count_padding("MTIzNA%3D%3d", {"%3d", "%3D"}));
ASSERT_EQ((padding{2, 6}), jwt::base::details::count_padding("MTIzNA%3D%3D", {"%3d", "%3D"}));
// Some fake scenarios
ASSERT_EQ(padding{}, jwt::base::details::count_padding("", {"~"}));
ASSERT_EQ(padding{}, jwt::base::details::count_padding("ABC", {"~", "~~!"}));
ASSERT_EQ(padding{}, jwt::base::details::count_padding("ABC!", {"~", "~~!"}));
ASSERT_EQ((padding{1, 1}), jwt::base::details::count_padding("ABC~", {"~", "~~!"}));
ASSERT_EQ((padding{1, 3}), jwt::base::details::count_padding("ABC~~!", {"~", "~~!"}));
ASSERT_EQ((padding{2, 2}), jwt::base::details::count_padding("ABC!~~", {"~", "~~!"}));
ASSERT_EQ((padding{3, 5}), jwt::base::details::count_padding("ABC~~!~~", {"~", "~~!"}));
ASSERT_EQ(padding{}, jwt::base::details::count_padding("ABC~~!~~", {}));
}
TEST(BaseTest, Base64Decode) {
ASSERT_EQ("1", jwt::base::decode<jwt::alphabet::base64>("MQ=="));
ASSERT_EQ("12", jwt::base::decode<jwt::alphabet::base64>("MTI="));
ASSERT_EQ("123", jwt::base::decode<jwt::alphabet::base64>("MTIz"));
ASSERT_EQ("1234", jwt::base::decode<jwt::alphabet::base64>("MTIzNA=="));
}
TEST(BaseTest, Base64DecodeURL) {
ASSERT_EQ("1", jwt::base::decode<jwt::alphabet::base64url>("MQ%3d%3d"));
ASSERT_EQ("12", jwt::base::decode<jwt::alphabet::base64url>("MTI%3d"));
ASSERT_EQ("123", jwt::base::decode<jwt::alphabet::base64url>("MTIz"));
ASSERT_EQ("1234", jwt::base::decode<jwt::alphabet::base64url>("MTIzNA%3d%3d"));
}
TEST(BaseTest, Base64DecodeURLCaseInsensitive) {
ASSERT_EQ("1", jwt::base::decode<jwt::alphabet::helper::base64url_percent_encoding>("MQ%3d%3d"));
ASSERT_EQ("1", jwt::base::decode<jwt::alphabet::helper::base64url_percent_encoding>("MQ%3D%3d"));
ASSERT_EQ("1", jwt::base::decode<jwt::alphabet::helper::base64url_percent_encoding>("MQ%3d%3D"));
ASSERT_EQ("12", jwt::base::decode<jwt::alphabet::helper::base64url_percent_encoding>("MTI%3d"));
ASSERT_EQ("123", jwt::base::decode<jwt::alphabet::helper::base64url_percent_encoding>("MTIz"));
ASSERT_EQ("1234", jwt::base::decode<jwt::alphabet::helper::base64url_percent_encoding>("MTIzNA%3d%3d"));
ASSERT_EQ("1234", jwt::base::decode<jwt::alphabet::helper::base64url_percent_encoding>("MTIzNA%3D%3D"));
}
TEST(BaseTest, Base64Encode) {
ASSERT_EQ("MQ==", jwt::base::encode<jwt::alphabet::base64>("1"));
ASSERT_EQ("MTI=", jwt::base::encode<jwt::alphabet::base64>("12"));
ASSERT_EQ("MTIz", jwt::base::encode<jwt::alphabet::base64>("123"));
ASSERT_EQ("MTIzNA==", jwt::base::encode<jwt::alphabet::base64>("1234"));
}
TEST(BaseTest, Base64EncodeURL) {
ASSERT_EQ("MQ%3d%3d", jwt::base::encode<jwt::alphabet::base64url>("1"));
ASSERT_EQ("MTI%3d", jwt::base::encode<jwt::alphabet::base64url>("12"));
ASSERT_EQ("MTIz", jwt::base::encode<jwt::alphabet::base64url>("123"));
ASSERT_EQ("MTIzNA%3d%3d", jwt::base::encode<jwt::alphabet::base64url>("1234"));
}
TEST(BaseTest, Base64Pad) {
ASSERT_EQ("MQ==", jwt::base::pad<jwt::alphabet::base64>("MQ"));
ASSERT_EQ("MTI=", jwt::base::pad<jwt::alphabet::base64>("MTI"));
ASSERT_EQ("MTIz", jwt::base::pad<jwt::alphabet::base64>("MTIz"));
ASSERT_EQ("MTIzNA==", jwt::base::pad<jwt::alphabet::base64>("MTIzNA"));
}
TEST(BaseTest, Base64PadURL) {
ASSERT_EQ("MQ%3d%3d", jwt::base::pad<jwt::alphabet::base64url>("MQ"));
ASSERT_EQ("MTI%3d", jwt::base::pad<jwt::alphabet::base64url>("MTI"));
ASSERT_EQ("MTIz", jwt::base::pad<jwt::alphabet::base64url>("MTIz"));
ASSERT_EQ("MTIzNA%3d%3d", jwt::base::pad<jwt::alphabet::base64url>("MTIzNA"));
}
TEST(BaseTest, Base64Trim) {
ASSERT_EQ("MQ", jwt::base::trim<jwt::alphabet::base64>("MQ=="));
ASSERT_EQ("MTI", jwt::base::trim<jwt::alphabet::base64>("MTI="));
ASSERT_EQ("MTIz", jwt::base::trim<jwt::alphabet::base64>("MTIz"));
ASSERT_EQ("MTIzNA", jwt::base::trim<jwt::alphabet::base64>("MTIzNA=="));
}
TEST(BaseTest, Base64TrimURL) {
ASSERT_EQ("MQ", jwt::base::trim<jwt::alphabet::base64url>("MQ%3d%3d"));
ASSERT_EQ("MTI", jwt::base::trim<jwt::alphabet::base64url>("MTI%3d"));
ASSERT_EQ("MTIz", jwt::base::trim<jwt::alphabet::base64url>("MTIz"));
ASSERT_EQ("MTIzNA", jwt::base::trim<jwt::alphabet::base64url>("MTIzNA%3d%3d"));
}
@@ -1,66 +0,0 @@
if(JWT_DISABLE_BASE64)
message(FATAL_ERROR "Tests requires the base64 support to be enabled!")
endif()
if(JWT_DISABLE_PICOJSON)
message(FATAL_ERROR "Tests requires the picojson support to be enabled!")
endif()
enable_testing()
include(GoogleTest)
if(HUNTER_ENABLED)
hunter_add_package(GTest)
endif()
find_package(GTest REQUIRED)
set(TEST_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/BaseTest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/ClaimTest.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Keys.cpp ${CMAKE_CURRENT_SOURCE_DIR}/HelperTest.cpp
${CMAKE_CURRENT_SOURCE_DIR}/TestMain.cpp ${CMAKE_CURRENT_SOURCE_DIR}/TokenFormatTest.cpp
${CMAKE_CURRENT_SOURCE_DIR}/TokenTest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/JwksTest.cpp
${CMAKE_CURRENT_SOURCE_DIR}/OpenSSLErrorTest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/traits/NlohmannTest.cpp)
find_package(jsoncons CONFIG)
if(TARGET jsoncons)
list(APPEND TEST_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/traits/JsonconsTest.cpp)
endif()
include("private-find-boost-json")
if(TARGET boost_json)
list(APPEND TEST_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/traits/BoostJsonTest.cpp)
endif()
add_executable(jwt-cpp-test ${TEST_SOURCES})
# NOTE: Don't use space inside a generator expression here, because the function prematurely breaks the expression into
# multiple lines. https://cmake.org/pipermail/cmake/2018-April/067422.html
set(JWT_TESTER_GCC_FLAGS -Wall -Wextra -Wpedantic)
set(JWT_TESTER_CLANG_FLAGS -Weverything -Wno-c++98-compat -Wno-global-constructors -Wno-weak-vtables)
target_compile_options(
jwt-cpp-test PRIVATE $<$<CXX_COMPILER_ID:MSVC>:/W4> $<$<CXX_COMPILER_ID:GNU>:${JWT_TESTER_GCC_FLAGS}>
$<$<CXX_COMPILER_ID:Clang>:${JWT_TESTER_CLANG_FLAGS}>)
if(HUNTER_ENABLED)
target_link_libraries(jwt-cpp-test PRIVATE GTest::gtest GTest::gtest_main)
# Define a compile define to bypass openssl error tests
target_compile_definitions(jwt-cpp-test PRIVATE HUNTER_ENABLED=1)
else()
target_link_libraries(jwt-cpp-test PRIVATE GTest::GTest GTest::Main)
if(TARGET jsoncons)
target_link_libraries(jwt-cpp-test PRIVATE jsoncons)
endif()
if(TARGET boost_json)
target_link_libraries(jwt-cpp-test PRIVATE boost_json)
endif()
endif()
target_link_libraries(jwt-cpp-test PRIVATE jwt-cpp nlohmann_json::nlohmann_json
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:${CMAKE_DL_LIBS}>)
gtest_add_tests(TARGET jwt-cpp-test)
if(JWT_ENABLE_COVERAGE)
include("code-coverage")
setup_coverage(jwt-cpp-test)
set(COVERAGE_EXCLUDES "/usr/**" "/home/*/.conan/**" "*test*" "*build*" "**/nlohmann/json.hpp"
"**/picojson/picojson.h" "*boost*" "*jsoncons*")
setup_target_for_coverage_lcov(NAME coverage EXECUTABLE ${CMAKE_CURRENT_BINARY_DIR}/jwt-cpp-test)
endif()
-141
View File
@@ -1,141 +0,0 @@
#include "jwt-cpp/jwt.h"
#include <gtest/gtest.h>
TEST(ClaimTest, AudienceAsString) {
std::string token =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJ0ZXN0In0.WZnM3SIiSRHsbO3O7Z2bmIzTJ4EC32HRBKfLznHhrh4";
auto decoded = jwt::decode(token);
ASSERT_TRUE(decoded.has_algorithm());
ASSERT_TRUE(decoded.has_type());
ASSERT_FALSE(decoded.has_content_type());
ASSERT_FALSE(decoded.has_key_id());
ASSERT_FALSE(decoded.has_issuer());
ASSERT_FALSE(decoded.has_subject());
ASSERT_TRUE(decoded.has_audience());
ASSERT_FALSE(decoded.has_expires_at());
ASSERT_FALSE(decoded.has_not_before());
ASSERT_FALSE(decoded.has_issued_at());
ASSERT_FALSE(decoded.has_id());
ASSERT_EQ("HS256", decoded.get_algorithm());
ASSERT_EQ("JWT", decoded.get_type());
auto aud = decoded.get_audience();
ASSERT_EQ(1, aud.size());
ASSERT_EQ("test", *aud.begin());
}
TEST(ClaimTest, SetAudienceAsString) {
auto token = jwt::create().set_type("JWT").set_audience("test").sign(jwt::algorithm::hs256("test"));
ASSERT_EQ("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJ0ZXN0In0.ny5Fa0vzAg7tNL95KWg_ecBNd3XP3tdAzq0SFA6diY4",
token);
}
TEST(ClaimTest, AudienceAsSet) {
std::string token = "eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJhdWQiOlsidGVzdCIsInRlc3QyIl19.";
auto decoded = jwt::decode(token);
ASSERT_TRUE(decoded.has_algorithm());
ASSERT_TRUE(decoded.has_type());
ASSERT_FALSE(decoded.has_content_type());
ASSERT_FALSE(decoded.has_key_id());
ASSERT_FALSE(decoded.has_issuer());
ASSERT_FALSE(decoded.has_subject());
ASSERT_TRUE(decoded.has_audience());
ASSERT_FALSE(decoded.has_expires_at());
ASSERT_FALSE(decoded.has_not_before());
ASSERT_FALSE(decoded.has_issued_at());
ASSERT_FALSE(decoded.has_id());
ASSERT_EQ("none", decoded.get_algorithm());
ASSERT_EQ("JWT", decoded.get_type());
auto aud = decoded.get_audience();
ASSERT_EQ(2, aud.size());
ASSERT_TRUE(aud.count("test") > 0);
ASSERT_TRUE(aud.count("test2") > 0);
}
TEST(ClaimTest, SetAudienceAsSet) {
auto token = jwt::create()
.set_type("JWT")
.set_audience({{picojson::value("test"), picojson::value("test2")}})
.sign(jwt::algorithm::none{});
ASSERT_EQ("eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJhdWQiOlsidGVzdCIsInRlc3QyIl19.", token);
}
TEST(ClaimTest, SetArray) {
std::vector<int64_t> vect = {100, 20, 10};
auto token =
jwt::create().set_payload_claim("test", jwt::claim(vect.begin(), vect.end())).sign(jwt::algorithm::none{});
ASSERT_EQ(token, "eyJhbGciOiJub25lIn0.eyJ0ZXN0IjpbMTAwLDIwLDEwXX0.");
}
TEST(ClaimTest, SetObject) {
std::istringstream iss{"{\"api-x\": [1]}"};
jwt::claim object;
iss >> object;
ASSERT_EQ(object.get_type(), jwt::json::type::object);
auto token = jwt::create().set_payload_claim("namespace", object).sign(jwt::algorithm::hs256("test"));
ASSERT_EQ(token,
"eyJhbGciOiJIUzI1NiJ9.eyJuYW1lc3BhY2UiOnsiYXBpLXgiOlsxXX19.F8I6I2RcSF98bKa0IpIz09fRZtHr1CWnWKx2za-tFQA");
}
TEST(ClaimTest, SetAlgorithm) {
auto token = jwt::create().set_algorithm("test").sign(jwt::algorithm::none{});
auto decoded_token = jwt::decode(token);
ASSERT_EQ(decoded_token.get_algorithm(), "test");
}
TEST(ClaimTest, AsInt) {
jwt::claim c(picojson::value(static_cast<int64_t>(10)));
ASSERT_EQ(c.as_integer(), 10);
}
TEST(ClaimTest, AsDate) {
jwt::claim c(picojson::value(static_cast<int64_t>(10)));
ASSERT_EQ(c.as_date(), std::chrono::system_clock::from_time_t(10));
}
TEST(ClaimTest, PicoJSONTraitsAccessorsThrow) {
jwt::traits::kazuho_picojson::value_type val;
ASSERT_THROW(jwt::traits::kazuho_picojson::as_array(val), std::bad_cast);
ASSERT_THROW(jwt::traits::kazuho_picojson::as_boolean(val), std::bad_cast);
ASSERT_THROW(jwt::traits::kazuho_picojson::as_integer(val), std::bad_cast);
ASSERT_THROW(jwt::traits::kazuho_picojson::as_number(val), std::bad_cast);
ASSERT_THROW(jwt::traits::kazuho_picojson::as_object(val), std::bad_cast);
ASSERT_THROW(jwt::traits::kazuho_picojson::as_string(val), std::bad_cast);
ASSERT_THROW(jwt::traits::kazuho_picojson::get_type(val), std::logic_error);
}
TEST(ClaimTest, PicoJSONTraitsAsBool) {
jwt::traits::kazuho_picojson::value_type val(true);
ASSERT_EQ(jwt::traits::kazuho_picojson::as_boolean(val), true);
ASSERT_EQ(jwt::traits::kazuho_picojson::get_type(val), jwt::json::type::boolean);
}
TEST(ClaimTest, PicoJSONTraitsAsDouble) {
jwt::traits::kazuho_picojson::value_type val(10.0);
ASSERT_EQ(jwt::traits::kazuho_picojson::as_number(val), (int)10);
ASSERT_EQ(jwt::traits::kazuho_picojson::get_type(val), jwt::json::type::number);
}
TEST(ClaimTest, MapOfClaim) {
using map = jwt::details::map_of_claims<jwt::traits::kazuho_picojson>;
ASSERT_THROW(map::parse_claims(R"##(__ not json __)##"), jwt::error::invalid_json_exception);
const map claims{
map::parse_claims(R"##({ "array": [1], "string" : "hello world", "number": 9.9, "bool": true})##")};
ASSERT_TRUE(claims.has_claim("array"));
ASSERT_TRUE(claims.has_claim("string"));
ASSERT_TRUE(claims.has_claim("number"));
ASSERT_TRUE(claims.has_claim("bool"));
ASSERT_FALSE(claims.has_claim("__missing__"));
ASSERT_EQ(map::basic_claim_t{claims.get_claim("array").as_array().at(0)}.as_integer(), (int)1);
ASSERT_EQ(claims.get_claim("string").as_string(), "hello world");
ASSERT_EQ(claims.get_claim("number").as_number(), 9.9);
ASSERT_EQ(claims.get_claim("bool").as_boolean(), true);
ASSERT_THROW(claims.get_claim("__missing__"), jwt::error::claim_not_present_exception);
}
-205
View File
@@ -1,205 +0,0 @@
#include "jwt-cpp/jwt.h"
#include <gtest/gtest.h>
namespace {
extern std::string google_cert;
extern std::string google_cert_base64_der;
extern std::string google_public_key;
} // namespace
TEST(HelperTest, Cert2Pubkey) {
auto key = jwt::helper::extract_pubkey_from_cert(google_cert);
ASSERT_EQ(google_public_key, key);
}
TEST(HelperTest, Base64DER2PemCert) {
auto cert_pem = jwt::helper::convert_base64_der_to_pem(google_cert_base64_der);
ASSERT_EQ(google_cert, cert_pem);
}
TEST(HelperTest, DER2PemCert) {
auto decoded =
jwt::base::decode<jwt::alphabet::base64>(jwt::base::pad<jwt::alphabet::base64>(google_cert_base64_der));
auto cert_pem = jwt::helper::convert_der_to_pem(decoded);
ASSERT_EQ(google_cert, cert_pem);
}
TEST(HelperTest, ErrorCodeMessages) {
ASSERT_EQ(std::error_code(jwt::error::rsa_error::ok).message(), "no error");
ASSERT_EQ(std::error_code(static_cast<jwt::error::rsa_error>(-1)).message(), "unknown RSA error");
ASSERT_EQ(std::error_code(jwt::error::rsa_error::ok).category().name(), std::string("rsa_error"));
ASSERT_EQ(std::error_code(jwt::error::ecdsa_error::ok).message(), "no error");
ASSERT_EQ(std::error_code(static_cast<jwt::error::ecdsa_error>(-1)).message(), "unknown ECDSA error");
ASSERT_EQ(std::error_code(jwt::error::ecdsa_error::ok).category().name(), std::string("ecdsa_error"));
ASSERT_EQ(std::error_code(jwt::error::signature_verification_error::ok).message(), "no error");
ASSERT_EQ(std::error_code(static_cast<jwt::error::signature_verification_error>(-1)).message(),
"unknown signature verification error");
ASSERT_EQ(std::error_code(jwt::error::signature_verification_error::ok).category().name(),
std::string("signature_verification_error"));
ASSERT_EQ(std::error_code(jwt::error::signature_generation_error::ok).message(), "no error");
ASSERT_EQ(std::error_code(static_cast<jwt::error::signature_generation_error>(-1)).message(),
"unknown signature generation error");
ASSERT_EQ(std::error_code(jwt::error::signature_generation_error::ok).category().name(),
std::string("signature_generation_error"));
ASSERT_EQ(std::error_code(jwt::error::token_verification_error::ok).message(), "no error");
ASSERT_EQ(std::error_code(static_cast<jwt::error::token_verification_error>(-1)).message(),
"unknown token verification error");
ASSERT_EQ(std::error_code(jwt::error::token_verification_error::ok).category().name(),
std::string("token_verification_error"));
int i = 10;
for (i = 10; i < 19; i++) {
ASSERT_NE(std::error_code(static_cast<jwt::error::rsa_error>(i)).message(),
std::error_code(static_cast<jwt::error::rsa_error>(-1)).message());
}
ASSERT_EQ(std::error_code(static_cast<jwt::error::rsa_error>(i)).message(),
std::error_code(static_cast<jwt::error::rsa_error>(-1)).message());
for (i = 10; i < 17; i++) {
ASSERT_NE(std::error_code(static_cast<jwt::error::ecdsa_error>(i)).message(),
std::error_code(static_cast<jwt::error::ecdsa_error>(-1)).message());
}
ASSERT_EQ(std::error_code(static_cast<jwt::error::ecdsa_error>(i)).message(),
std::error_code(static_cast<jwt::error::ecdsa_error>(-1)).message());
for (i = 10; i < 18; i++) {
ASSERT_NE(std::error_code(static_cast<jwt::error::signature_verification_error>(i)).message(),
std::error_code(static_cast<jwt::error::signature_verification_error>(-1)).message());
}
ASSERT_EQ(std::error_code(static_cast<jwt::error::signature_verification_error>(i)).message(),
std::error_code(static_cast<jwt::error::signature_verification_error>(-1)).message());
for (i = 10; i < 24; i++) {
ASSERT_NE(std::error_code(static_cast<jwt::error::signature_generation_error>(i)).message(),
std::error_code(static_cast<jwt::error::signature_generation_error>(-1)).message());
}
ASSERT_EQ(std::error_code(static_cast<jwt::error::signature_generation_error>(i)).message(),
std::error_code(static_cast<jwt::error::signature_generation_error>(-1)).message());
for (i = 10; i < 16; i++) {
ASSERT_NE(std::error_code(static_cast<jwt::error::token_verification_error>(i)).message(),
std::error_code(static_cast<jwt::error::token_verification_error>(-1)).message());
}
ASSERT_EQ(std::error_code(static_cast<jwt::error::token_verification_error>(i)).message(),
std::error_code(static_cast<jwt::error::token_verification_error>(-1)).message());
}
namespace {
std::string google_cert =
// This is to handle the different subject alternate name ordering
// see https://github.com/wolfSSL/wolfssl/issues/4397
#ifdef LIBWOLFSSL_VERSION_HEX
R"(-----BEGIN CERTIFICATE-----
MIIFfTCCBOagAwIBAgIKYFOB9QABAACIvTANBgkqhkiG9w0BAQUFADBGMQswCQYD
VQQGEwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzEiMCAGA1UEAxMZR29vZ2xlIElu
dGVybmV0IEF1dGhvcml0eTAeFw0xMzA1MjIxNTQ5MDRaFw0xMzEwMzEyMzU5NTla
MGYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1N
b3VudGFpbiBWaWV3MRMwEQYDVQQKEwpHb29nbGUgSW5jMRUwEwYDVQQDDAwqLmdv
b2dsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARmSpIUbCqhUBq1UwnR
Ai7/TNSk6W8JmasR+I0r/NLDYv5yApbAz8HXXN8hDdurMRP6Jy1Q0UIKmyls8HPH
exoCo4IDlzCCA5MwggLDBgNVHREEggK6MIICtoIMKi5nb29nbGUuY29tgg0qLmFu
ZHJvaWQuY29tghYqLmFwcGVuZ2luZS5nb29nbGUuY29tghIqLmNsb3VkLmdvb2ds
ZS5jb22CFiouZ29vZ2xlLWFuYWx5dGljcy5jb22CCyouZ29vZ2xlLmNhggsqLmdv
b2dsZS5jbIIOKi5nb29nbGUuY28uaW6CDiouZ29vZ2xlLmNvLmpwgg4qLmdvb2ds
ZS5jby51a4IPKi5nb29nbGUuY29tLmFygg8qLmdvb2dsZS5jb20uYXWCDyouZ29v
Z2xlLmNvbS5icoIPKi5nb29nbGUuY29tLmNvgg8qLmdvb2dsZS5jb20ubXiCDyou
Z29vZ2xlLmNvbS50coIPKi5nb29nbGUuY29tLnZuggsqLmdvb2dsZS5kZYILKi5n
b29nbGUuZXOCCyouZ29vZ2xlLmZyggsqLmdvb2dsZS5odYILKi5nb29nbGUuaXSC
CyouZ29vZ2xlLm5sggsqLmdvb2dsZS5wbIILKi5nb29nbGUucHSCDyouZ29vZ2xl
YXBpcy5jboIUKi5nb29nbGVjb21tZXJjZS5jb22CDSouZ3N0YXRpYy5jb22CDCou
dXJjaGluLmNvbYIQKi51cmwuZ29vZ2xlLmNvbYIWKi55b3V0dWJlLW5vY29va2ll
LmNvbYINKi55b3V0dWJlLmNvbYIWKi55b3V0dWJlZWR1Y2F0aW9uLmNvbYILKi55
dGltZy5jb22CC2FuZHJvaWQuY29tggRnLmNvggZnb28uZ2yCFGdvb2dsZS1hbmFs
eXRpY3MuY29tggpnb29nbGUuY29tghJnb29nbGVjb21tZXJjZS5jb22CCnVyY2hp
bi5jb22CCHlvdXR1LmJlggt5b3V0dWJlLmNvbYIUeW91dHViZWVkdWNhdGlvbi5j
b20wHQYDVR0OBBYEFFN409DVTUYFOWYp0Rxq5cqBhJ6GMB8GA1UdIwQYMBaAFL/A
MOv1QxE+Z7qekfv8atrjaxIkMFsGA1UdHwRUMFIwUKBOoEyGSmh0dHA6Ly93d3cu
Z3N0YXRpYy5jb20vR29vZ2xlSW50ZXJuZXRBdXRob3JpdHkvR29vZ2xlSW50ZXJu
ZXRBdXRob3JpdHkuY3JsMA4GA1UdDwEB/wQEAwIHgDAdBgNVHSUEFjAUBggrBgEF
BQcDAQYIKwYBBQUHAwIwDQYJKoZIhvcNAQEFBQADgYEAAyfQrePfKEL5f67KHp4A
FrYSrvGJjn+ZQHzzoivX2/GW5Iw0oPqf+Jjy8eO2ufQGG5bz++YnK50WQhwQNRgT
iK9AyWx8gvtI4bDo569UuabTZqJEdaPlPbQOz5I6m55hQbc0Fwc//kjOFRghAlsb
OVBpRpkExpB4LxmyUw0tYjY=
-----END CERTIFICATE-----
)";
#else
R"(-----BEGIN CERTIFICATE-----
MIIF8DCCBVmgAwIBAgIKYFOB9QABAACIvTANBgkqhkiG9w0BAQUFADBGMQswCQYD
VQQGEwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzEiMCAGA1UEAxMZR29vZ2xlIElu
dGVybmV0IEF1dGhvcml0eTAeFw0xMzA1MjIxNTQ5MDRaFw0xMzEwMzEyMzU5NTla
MGYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1N
b3VudGFpbiBWaWV3MRMwEQYDVQQKEwpHb29nbGUgSW5jMRUwEwYDVQQDFAwqLmdv
b2dsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARmSpIUbCqhUBq1UwnR
Ai7/TNSk6W8JmasR+I0r/NLDYv5yApbAz8HXXN8hDdurMRP6Jy1Q0UIKmyls8HPH
exoCo4IECjCCBAYwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMAsGA1Ud
DwQEAwIHgDAdBgNVHQ4EFgQUU3jT0NVNRgU5ZinRHGrlyoGEnoYwHwYDVR0jBBgw
FoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0fBFQwUjBQoE6gTIZKaHR0cDov
L3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS9Hb29nbGVJ
bnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUHAQEEWjBYMFYGCCsGAQUFBzAC
hkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2dsZUludGVybmV0QXV0aG9yaXR5
L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDAMBgNVHRMBAf8EAjAAMIICwwYD
VR0RBIICujCCAraCDCouZ29vZ2xlLmNvbYINKi5hbmRyb2lkLmNvbYIWKi5hcHBl
bmdpbmUuZ29vZ2xlLmNvbYISKi5jbG91ZC5nb29nbGUuY29tghYqLmdvb2dsZS1h
bmFseXRpY3MuY29tggsqLmdvb2dsZS5jYYILKi5nb29nbGUuY2yCDiouZ29vZ2xl
LmNvLmlugg4qLmdvb2dsZS5jby5qcIIOKi5nb29nbGUuY28udWuCDyouZ29vZ2xl
LmNvbS5hcoIPKi5nb29nbGUuY29tLmF1gg8qLmdvb2dsZS5jb20uYnKCDyouZ29v
Z2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20udHKCDyou
Z29vZ2xlLmNvbS52boILKi5nb29nbGUuZGWCCyouZ29vZ2xlLmVzggsqLmdvb2ds
ZS5mcoILKi5nb29nbGUuaHWCCyouZ29vZ2xlLml0ggsqLmdvb2dsZS5ubIILKi5n
b29nbGUucGyCCyouZ29vZ2xlLnB0gg8qLmdvb2dsZWFwaXMuY26CFCouZ29vZ2xl
Y29tbWVyY2UuY29tgg0qLmdzdGF0aWMuY29tggwqLnVyY2hpbi5jb22CECoudXJs
Lmdvb2dsZS5jb22CFioueW91dHViZS1ub2Nvb2tpZS5jb22CDSoueW91dHViZS5j
b22CFioueW91dHViZWVkdWNhdGlvbi5jb22CCyoueXRpbWcuY29tggthbmRyb2lk
LmNvbYIEZy5jb4IGZ29vLmdsghRnb29nbGUtYW5hbHl0aWNzLmNvbYIKZ29vZ2xl
LmNvbYISZ29vZ2xlY29tbWVyY2UuY29tggp1cmNoaW4uY29tggh5b3V0dS5iZYIL
eW91dHViZS5jb22CFHlvdXR1YmVlZHVjYXRpb24uY29tMA0GCSqGSIb3DQEBBQUA
A4GBAAMn0K3j3yhC+X+uyh6eABa2Eq7xiY5/mUB886Ir19vxluSMNKD6n/iY8vHj
trn0BhuW8/vmJyudFkIcEDUYE4ivQMlsfIL7SOGw6OevVLmm02aiRHWj5T20Ds+S
OpueYUG3NBcHP/5IzhUYIQJbGzlQaUaZBMaQeC8ZslMNLWI2
-----END CERTIFICATE-----
)";
#endif
std::string google_cert_base64_der = "MIIF8DCCBVmgAwIBAgIKYFOB9QABAACIvTANBgkqhkiG9w0BAQUFADBGMQswCQYD"
"VQQGEwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzEiMCAGA1UEAxMZR29vZ2xlIElu"
"dGVybmV0IEF1dGhvcml0eTAeFw0xMzA1MjIxNTQ5MDRaFw0xMzEwMzEyMzU5NTla"
"MGYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1N"
"b3VudGFpbiBWaWV3MRMwEQYDVQQKEwpHb29nbGUgSW5jMRUwEwYDVQQDFAwqLmdv"
"b2dsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARmSpIUbCqhUBq1UwnR"
"Ai7/TNSk6W8JmasR+I0r/NLDYv5yApbAz8HXXN8hDdurMRP6Jy1Q0UIKmyls8HPH"
"exoCo4IECjCCBAYwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMAsGA1Ud"
"DwQEAwIHgDAdBgNVHQ4EFgQUU3jT0NVNRgU5ZinRHGrlyoGEnoYwHwYDVR0jBBgw"
"FoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0fBFQwUjBQoE6gTIZKaHR0cDov"
"L3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS9Hb29nbGVJ"
"bnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUHAQEEWjBYMFYGCCsGAQUFBzAC"
"hkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2dsZUludGVybmV0QXV0aG9yaXR5"
"L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDAMBgNVHRMBAf8EAjAAMIICwwYD"
"VR0RBIICujCCAraCDCouZ29vZ2xlLmNvbYINKi5hbmRyb2lkLmNvbYIWKi5hcHBl"
"bmdpbmUuZ29vZ2xlLmNvbYISKi5jbG91ZC5nb29nbGUuY29tghYqLmdvb2dsZS1h"
"bmFseXRpY3MuY29tggsqLmdvb2dsZS5jYYILKi5nb29nbGUuY2yCDiouZ29vZ2xl"
"LmNvLmlugg4qLmdvb2dsZS5jby5qcIIOKi5nb29nbGUuY28udWuCDyouZ29vZ2xl"
"LmNvbS5hcoIPKi5nb29nbGUuY29tLmF1gg8qLmdvb2dsZS5jb20uYnKCDyouZ29v"
"Z2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20udHKCDyou"
"Z29vZ2xlLmNvbS52boILKi5nb29nbGUuZGWCCyouZ29vZ2xlLmVzggsqLmdvb2ds"
"ZS5mcoILKi5nb29nbGUuaHWCCyouZ29vZ2xlLml0ggsqLmdvb2dsZS5ubIILKi5n"
"b29nbGUucGyCCyouZ29vZ2xlLnB0gg8qLmdvb2dsZWFwaXMuY26CFCouZ29vZ2xl"
"Y29tbWVyY2UuY29tgg0qLmdzdGF0aWMuY29tggwqLnVyY2hpbi5jb22CECoudXJs"
"Lmdvb2dsZS5jb22CFioueW91dHViZS1ub2Nvb2tpZS5jb22CDSoueW91dHViZS5j"
"b22CFioueW91dHViZWVkdWNhdGlvbi5jb22CCyoueXRpbWcuY29tggthbmRyb2lk"
"LmNvbYIEZy5jb4IGZ29vLmdsghRnb29nbGUtYW5hbHl0aWNzLmNvbYIKZ29vZ2xl"
"LmNvbYISZ29vZ2xlY29tbWVyY2UuY29tggp1cmNoaW4uY29tggh5b3V0dS5iZYIL"
"eW91dHViZS5jb22CFHlvdXR1YmVlZHVjYXRpb24uY29tMA0GCSqGSIb3DQEBBQUA"
"A4GBAAMn0K3j3yhC+X+uyh6eABa2Eq7xiY5/mUB886Ir19vxluSMNKD6n/iY8vHj"
"trn0BhuW8/vmJyudFkIcEDUYE4ivQMlsfIL7SOGw6OevVLmm02aiRHWj5T20Ds+S"
"OpueYUG3NBcHP/5IzhUYIQJbGzlQaUaZBMaQeC8ZslMNLWI2";
std::string google_public_key = R"(-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEZkqSFGwqoVAatVMJ0QIu/0zUpOlv
CZmrEfiNK/zSw2L+cgKWwM/B11zfIQ3bqzET+ictUNFCCpspbPBzx3saAg==
-----END PUBLIC KEY-----
)";
} // namespace
-118
View File
@@ -1,118 +0,0 @@
#include "jwt-cpp/jwt.h"
#include <gtest/gtest.h>
TEST(JwksTest, OneKeyParse) {
std::string public_key = R"({
"alg": "RS256",
"kty": "RSA",
"use": "sig",
"x5c": [
"MIIC+DCCAeCgAwIBAgIJBIGjYW6hFpn2MA0GCSqGSIb3DQEBBQUAMCMxITAfBgNVBAMTGGN1c3RvbWVyLWRlbW9zLmF1dGgwLmNvbTAeFw0xNjExMjIyMjIyMDVaFw0zMDA4MDEyMjIyMDVaMCMxITAfBgNVBAMTGGN1c3RvbWVyLWRlbW9zLmF1dGgwLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMnjZc5bm/eGIHq09N9HKHahM7Y31P0ul+A2wwP4lSpIwFrWHzxw88/7Dwk9QMc+orGXX95R6av4GF+Es/nG3uK45ooMVMa/hYCh0Mtx3gnSuoTavQEkLzCvSwTqVwzZ+5noukWVqJuMKNwjL77GNcPLY7Xy2/skMCT5bR8UoWaufooQvYq6SyPcRAU4BtdquZRiBT4U5f+4pwNTxSvey7ki50yc1tG49Per/0zA4O6Tlpv8x7Red6m1bCNHt7+Z5nSl3RX/QYyAEUX1a28VcYmR41Osy+o2OUCXYdUAphDaHo4/8rbKTJhlu8jEcc1KoMXAKjgaVZtG/v5ltx6AXY0CAwEAAaMvMC0wDAYDVR0TBAUwAwEB/zAdBgNVHQ4EFgQUQxFG602h1cG+pnyvJoy9pGJJoCswDQYJKoZIhvcNAQEFBQADggEBAGvtCbzGNBUJPLICth3mLsX0Z4z8T8iu4tyoiuAshP/Ry/ZBnFnXmhD8vwgMZ2lTgUWwlrvlgN+fAtYKnwFO2G3BOCFw96Nm8So9sjTda9CCZ3dhoH57F/hVMBB0K6xhklAc0b5ZxUpCIN92v/w+xZoz1XQBHe8ZbRHaP1HpRM4M7DJk2G5cgUCyu3UBvYS41sHvzrxQ3z7vIePRA4WF4bEkfX12gvny0RsPkrbVMXX1Rj9t6V7QXrbPYBAO+43JvDGYawxYVvLhz+BJ45x50GFQmHszfY3BR9TPK8xmMmQwtIvLu1PMttNCs7niCYkSiUv2sc2mlq1i3IashGkkgmo="
],
"n": "yeNlzlub94YgerT030codqEztjfU_S6X4DbDA_iVKkjAWtYfPHDzz_sPCT1Axz6isZdf3lHpq_gYX4Sz-cbe4rjmigxUxr-FgKHQy3HeCdK6hNq9ASQvMK9LBOpXDNn7mei6RZWom4wo3CMvvsY1w8tjtfLb-yQwJPltHxShZq5-ihC9irpLI9xEBTgG12q5lGIFPhTl_7inA1PFK97LuSLnTJzW0bj096v_TMDg7pOWm_zHtF53qbVsI0e3v5nmdKXdFf9BjIARRfVrbxVxiZHjU6zL6jY5QJdh1QCmENoejj_ytspMmGW7yMRxzUqgxcAqOBpVm0b-_mW3HoBdjQ",
"e": "AQAB",
"kid": "123456789",
"x5t": "NjVBRjY5MDlCMUIwNzU4RTA2QzZFMDQ4QzQ2MDAyQjVDNjk1RTM2Qg"
})";
ASSERT_THROW(jwt::parse_jwk("__not_json__"), jwt::error::invalid_json_exception);
ASSERT_THROW(jwt::parse_jwk(R"##(["not","an","object"])##"), std::bad_cast);
auto jwk = jwt::parse_jwk(public_key);
ASSERT_TRUE(jwk.has_algorithm());
ASSERT_TRUE(jwk.has_key_id());
ASSERT_TRUE(jwk.has_x5c());
ASSERT_FALSE(jwk.has_jwk_claim("foo"));
ASSERT_EQ("RS256", jwk.get_algorithm());
ASSERT_EQ("123456789", jwk.get_key_id());
}
TEST(JwksTest, MultiKeysParse) {
std::string public_key = R"({
"keys": [{
"kid": "internal-gateway-jwt",
"use": "sig",
"x5c": ["MIIG1TCCBL2gAwIBAgIIFvMVGp6t\/cMwDQYJKoZIhvcNAQELBQAwZjELMAkGA1UEBhMCR0IxIDAeBgNVBAoMF1N0YW5kYXJkIENoYXJ0ZXJlZCBCYW5rMTUwMwYDVQQDDCxTdGFuZGFyZCBDaGFydGVyZWQgQmFuayBTaWduaW5nIENBIEcxIC0gU0hBMjAeFw0xODEwMTAxMTI2MzVaFw0yMjEwMTAxMTI2MzVaMIG9MQswCQYDVQQGEwJTRzESMBAGA1UECAwJU2luZ2Fwb3JlMRIwEAYDVQQHDAlTaW5nYXBvcmUxIDAeBgNVBAoMF1N0YW5kYXJkIENoYXJ0ZXJlZCBCYW5rMRwwGgYDVQQLDBNGb3VuZGF0aW9uIFNlcnZpY2VzMSgwJgYDVQQDDB9pbnRlcm5hbC1nYXRld2F5LWp3dC5hcGkuc2MubmV0MRwwGgYJKoZIhvcNAQkBFg1BUElQU1NAc2MuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArVWBoIi3IJ4nOWXu7\/SDxczqMou1B+c4c2FdQrOXrK31HxAaz4WEtma9BLXFdFHJ5mCCPIvdUcVxxnCynqhMOkZ\/a7acQbUD9cDzI8isMB9JL7VooDw0CctxHxffjqQQVIEhC2Q7zsM1pQayR7cl+pbBlvHIoRxq2n1B0fFvfoiosjf4kDiCpgHdM+v5Hw9aVYmUbroHxmQWqhB0iRTJQPPLZqqQVC50A1Q\/96gkwoODyotc46Uy9wYEpdGrtDG\/thWay3fmMsjpWR0U25xFIrxTrfCGBblYpD7juukWWml2E9rtE2rHgUxbymxXjEw7xrMwcGrhOGyqwoBqJy1JVwIDAQABo4ICLTCCAikwZAYIKwYBBQUHAQEEWDBWMFQGCCsGAQUFBzABhkhodHRwOi8vY29yZW9jc3AuZ2xvYmFsLnN0YW5kYXJkY2hhcnRlcmVkLmNvbS9lamJjYS9wdWJsaWN3ZWIvc3RhdHVzL29jc3AwHQYDVR0OBBYEFIinW4BNDeVEFcuLf8YjZjtySoW9MAwGA1UdEwEB\/wQCMAAwHwYDVR0jBBgwFoAUfNZMoZi33nKrcmVU3TFVQnuEi\/4wggFCBgNVHR8EggE5MIIBNTCCATGggcKggb+GgbxodHRwOi8vY29yZWNybC5nbG9iYWwuc3RhbmRhcmRjaGFydGVyZWQuY29tL2VqYmNhL3B1YmxpY3dlYi93ZWJkaXN0L2NlcnRkaXN0P2NtZD1jcmwmaXNzdWVyPUNOPVN0YW5kYXJkJTIwQ2hhcnRlcmVkJTIwQmFuayUyMFNpZ25pbmclMjBDQSUyMEcxJTIwLSUyMFNIQTIsTz1TdGFuZGFyZCUyMENoYXJ0ZXJlZCUyMEJhbmssQz1HQqJqpGgwZjE1MDMGA1UEAwwsU3RhbmRhcmQgQ2hhcnRlcmVkIEJhbmsgU2lnbmluZyBDQSBHMSAtIFNIQTIxIDAeBgNVBAoMF1N0YW5kYXJkIENoYXJ0ZXJlZCBCYW5rMQswCQYDVQQGEwJHQjAOBgNVHQ8BAf8EBAMCBsAwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMA0GCSqGSIb3DQEBCwUAA4ICAQBtsoRlDHuOTDChcWdfdVUtRgP0U0ijDSeJi8vULN1rgYnqqJc4PdJno50aiu9MGlxY02O7HW7ZVD6QEG\/pqHmZ0sbWpb\/fumMgZSjP65IcGuS53zgcNtLYnyXyEv+v5T\/CK3bk4Li6tUW3ScJPUwVWwP1E0\/u6aBSb5k\/h4lTwS1o88ybS5pJOg6XutXByp991QQrrs7tp7fKNynjNZbFuG3J1e09X+zTfJOpjaDUofQTkt8IyMRI6Cs4wI1eZA+dAIL8B0n8ze1mRl1FOJqgdZrAQjoqZkCTnc0Il5VY\/dUXxGVg6D9e5pfck3FWT107K9\/5EZoxytpqYXFCjMXi5hx4YjK17OUgm82mZhvqkNdzF8Yq2vFuB3LPfyelESq99xFLykvinrVm1NtZKeDTT1Jq\/VvZt6stO\/tovq1RfJJcznpYcwOzxlnhGR6E+hxuBx7aDJzGf0JaoRxQILH1B2XV9WDI3HPYQsP7XtriX+QUJ\/aly28QkV48RmaGYCsly43YZu1MKudSsw+dhnbZzRsg\/aes3dzGW2x137bQPtux7k2LCSpsTXgedhOys28YoGlsoe8kUv0myAU4Stt+I3mrwO3BKUn+tJggvlDiiiyT1tg2HiklyU\/2FxQkZRMeB0eRrXTpg3l9x2mpF+dDFxOMKszxwD2kgoEZgo6o58A=="],
"n": "nr9UsxnPVd21iuiGcIJ_Qli2XVlAZe5VbELA1hO2-L4k5gI4fjHZ3ysUcautLpbOYogOQgsnlpsLrCmvNDvBDVzVp2nMbpguJlt12vHSP1fRJJpipGQ8qU-VaXsC4OjOQf3H9ojAU5Vfnl5gZ7kVCd8g4M29l-IRyNpxE-Ccxc2Y7molsCHT6GHLMMBVsd11JIOXMICJf4hz2YYkQ1t7C8SaB2RFRPuGO5Mn6mfAnwdmRera4TBz6_pIPPCgCbN8KOdJItWkr9F7Tjv_0nhh-ZVlQvbQ9PXHyKTj00g3IYUlbZIWHm0Ley__fzNZk2dyAAVjNA2QSzTZJc33MQx1pQ",
"e": "AQAB",
"x5t": "-qC0akuyiHT7GcV5a8O5nrFsKVWM9da7lzq6DLrj09I",
"alg": "RS256",
"kty": "RSA"
},
{
"kid": "internal-0",
"use": "sig",
"x5c": ["MIIG1TCCBL2gAwIBAgIIFvMVGp6t\/cMwDQYJKoZIhvcNAQELBQAwZjELMAkGA1UEBhMCR0IxIDAeBgNVBAoMF1N0YW5kYXJkIENoYXJ0ZXJlZCBCYW5rMTUwMwYDVQQDDCxTdGFuZGFyZCBDaGFydGVyZWQgQmFuayBTaWduaW5nIENBIEcxIC0gU0hBMjAeFw0xODEwMTAxMTI2MzVaFw0yMjEwMTAxMTI2MzVaMIG9MQswCQYDVQQGEwJTRzESMBAGA1UECAwJU2luZ2Fwb3JlMRIwEAYDVQQHDAlTaW5nYXBvcmUxIDAeBgNVBAoMF1N0YW5kYXJkIENoYXJ0ZXJlZCBCYW5rMRwwGgYDVQQLDBNGb3VuZGF0aW9uIFNlcnZpY2VzMSgwJgYDVQQDDB9pbnRlcm5hbC1nYXRld2F5LWp3dC5hcGkuc2MubmV0MRwwGgYJKoZIhvcNAQkBFg1BUElQU1NAc2MuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArVWBoIi3IJ4nOWXu7\/SDxczqMou1B+c4c2FdQrOXrK31HxAaz4WEtma9BLXFdFHJ5mCCPIvdUcVxxnCynqhMOkZ\/a7acQbUD9cDzI8isMB9JL7VooDw0CctxHxffjqQQVIEhC2Q7zsM1pQayR7cl+pbBlvHIoRxq2n1B0fFvfoiosjf4kDiCpgHdM+v5Hw9aVYmUbroHxmQWqhB0iRTJQPPLZqqQVC50A1Q\/96gkwoODyotc46Uy9wYEpdGrtDG\/thWay3fmMsjpWR0U25xFIrxTrfCGBblYpD7juukWWml2E9rtE2rHgUxbymxXjEw7xrMwcGrhOGyqwoBqJy1JVwIDAQABo4ICLTCCAikwZAYIKwYBBQUHAQEEWDBWMFQGCCsGAQUFBzABhkhodHRwOi8vY29yZW9jc3AuZ2xvYmFsLnN0YW5kYXJkY2hhcnRlcmVkLmNvbS9lamJjYS9wdWJsaWN3ZWIvc3RhdHVzL29jc3AwHQYDVR0OBBYEFIinW4BNDeVEFcuLf8YjZjtySoW9MAwGA1UdEwEB\/wQCMAAwHwYDVR0jBBgwFoAUfNZMoZi33nKrcmVU3TFVQnuEi\/4wggFCBgNVHR8EggE5MIIBNTCCATGggcKggb+GgbxodHRwOi8vY29yZWNybC5nbG9iYWwuc3RhbmRhcmRjaGFydGVyZWQuY29tL2VqYmNhL3B1YmxpY3dlYi93ZWJkaXN0L2NlcnRkaXN0P2NtZD1jcmwmaXNzdWVyPUNOPVN0YW5kYXJkJTIwQ2hhcnRlcmVkJTIwQmFuayUyMFNpZ25pbmclMjBDQSUyMEcxJTIwLSUyMFNIQTIsTz1TdGFuZGFyZCUyMENoYXJ0ZXJlZCUyMEJhbmssQz1HQqJqpGgwZjE1MDMGA1UEAwwsU3RhbmRhcmQgQ2hhcnRlcmVkIEJhbmsgU2lnbmluZyBDQSBHMSAtIFNIQTIxIDAeBgNVBAoMF1N0YW5kYXJkIENoYXJ0ZXJlZCBCYW5rMQswCQYDVQQGEwJHQjAOBgNVHQ8BAf8EBAMCBsAwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMA0GCSqGSIb3DQEBCwUAA4ICAQBtsoRlDHuOTDChcWdfdVUtRgP0U0ijDSeJi8vULN1rgYnqqJc4PdJno50aiu9MGlxY02O7HW7ZVD6QEG\/pqHmZ0sbWpb\/fumMgZSjP65IcGuS53zgcNtLYnyXyEv+v5T\/CK3bk4Li6tUW3ScJPUwVWwP1E0\/u6aBSb5k\/h4lTwS1o88ybS5pJOg6XutXByp991QQrrs7tp7fKNynjNZbFuG3J1e09X+zTfJOpjaDUofQTkt8IyMRI6Cs4wI1eZA+dAIL8B0n8ze1mRl1FOJqgdZrAQjoqZkCTnc0Il5VY\/dUXxGVg6D9e5pfck3FWT107K9\/5EZoxytpqYXFCjMXi5hx4YjK17OUgm82mZhvqkNdzF8Yq2vFuB3LPfyelESq99xFLykvinrVm1NtZKeDTT1Jq\/VvZt6stO\/tovq1RfJJcznpYcwOzxlnhGR6E+hxuBx7aDJzGf0JaoRxQILH1B2XV9WDI3HPYQsP7XtriX+QUJ\/aly28QkV48RmaGYCsly43YZu1MKudSsw+dhnbZzRsg\/aes3dzGW2x137bQPtux7k2LCSpsTXgedhOys28YoGlsoe8kUv0myAU4Stt+I3mrwO3BKUn+tJggvlDiiiyT1tg2HiklyU\/2FxQkZRMeB0eRrXTpg3l9x2mpF+dDFxOMKszxwD2kgoEZgo6o58A=="],
"n": "nr9UsxnPVd21iuiGcIJ_Qli2XVlAZe5VbELA1hO2-L4k5gI4fjHZ3ysUcautLpbOYogOQgsnlpsLrCmvNDvBDVzVp2nMbpguJlt12vHSP1fRJJpipGQ8qU-VaXsC4OjOQf3H9ojAU5Vfnl5gZ7kVCd8g4M29l-IRyNpxE-Ccxc2Y7molsCHT6GHLMMBVsd11JIOXMICJf4hz2YYkQ1t7C8SaB2RFRPuGO5Mn6mfAnwdmRera4TBz6_pIPPCgCbN8KOdJItWkr9F7Tjv_0nhh-ZVlQvbQ9PXHyKTj00g3IYUlbZIWHm0Ley__fzNZk2dyAAVjNA2QSzTZJc33MQx1pQ",
"e": "AQAB",
"x5t": "-qC0akuyiHT7GcV5a8O5nrFsKVWM9da7lzq6DLrj09I",
"alg": "RS256",
"kty": "RSA"
}
]
})";
auto jwks = jwt::parse_jwks(public_key);
auto jwk = jwks.get_jwk("internal-gateway-jwt");
ASSERT_TRUE(jwk.has_algorithm());
ASSERT_TRUE(jwk.has_key_id());
ASSERT_TRUE(jwk.has_x5c());
ASSERT_FALSE(jwk.has_jwk_claim("foo"));
ASSERT_EQ("RS256", jwk.get_algorithm());
ASSERT_EQ("internal-gateway-jwt", jwk.get_key_id());
ASSERT_THROW(jwks.get_jwk("123456"), jwt::error::claim_not_present_exception);
}
TEST(JwksTest, Missingx5c) {
std::string public_key = R"({
"keys": [{
"kid": "internal-gateway-jwt",
"use": "sig",
"n": "nr9UsxnPVd21iuiGcIJ_Qli2XVlAZe5VbELA1hO2-L4k5gI4fjHZ3ysUcautLpbOYogOQgsnlpsLrCmvNDvBDVzVp2nMbpguJlt12vHSP1fRJJpipGQ8qU-VaXsC4OjOQf3H9ojAU5Vfnl5gZ7kVCd8g4M29l-IRyNpxE-Ccxc2Y7molsCHT6GHLMMBVsd11JIOXMICJf4hz2YYkQ1t7C8SaB2RFRPuGO5Mn6mfAnwdmRera4TBz6_pIPPCgCbN8KOdJItWkr9F7Tjv_0nhh-ZVlQvbQ9PXHyKTj00g3IYUlbZIWHm0Ley__fzNZk2dyAAVjNA2QSzTZJc33MQx1pQ",
"e": "AQAB",
"x5t": "-qC0akuyiHT7GcV5a8O5nrFsKVWM9da7lzq6DLrj09I",
"alg": "RS256",
"kty": "RSA"
},
{
"kid": "internal-0",
"use": "sig",
"x5c": [],
"n": "nr9UsxnPVd21iuiGcIJ_Qli2XVlAZe5VbELA1hO2-L4k5gI4fjHZ3ysUcautLpbOYogOQgsnlpsLrCmvNDvBDVzVp2nMbpguJlt12vHSP1fRJJpipGQ8qU-VaXsC4OjOQf3H9ojAU5Vfnl5gZ7kVCd8g4M29l-IRyNpxE-Ccxc2Y7molsCHT6GHLMMBVsd11JIOXMICJf4hz2YYkQ1t7C8SaB2RFRPuGO5Mn6mfAnwdmRera4TBz6_pIPPCgCbN8KOdJItWkr9F7Tjv_0nhh-ZVlQvbQ9PXHyKTj00g3IYUlbZIWHm0Ley__fzNZk2dyAAVjNA2QSzTZJc33MQx1pQ",
"e": "AQAB",
"x5t": "-qC0akuyiHT7GcV5a8O5nrFsKVWM9da7lzq6DLrj09I",
"alg": "RS256",
"kty": "RSA"
},
{
"kid": "internal-1",
"x5c": ["1","2","3"],
"n": "nr9UsxnPVd21iuiGcIJ_Qli2XVlAZe5VbELA1hO2-L4k5gI4fjHZ3ysUcautLpbOYogOQgsnlpsLrCmvNDvBDVzVp2nMbpguJlt12vHSP1fRJJpipGQ8qU-VaXsC4OjOQf3H9ojAU5Vfnl5gZ7kVCd8g4M29l-IRyNpxE-Ccxc2Y7molsCHT6GHLMMBVsd11JIOXMICJf4hz2YYkQ1t7C8SaB2RFRPuGO5Mn6mfAnwdmRera4TBz6_pIPPCgCbN8KOdJItWkr9F7Tjv_0nhh-ZVlQvbQ9PXHyKTj00g3IYUlbZIWHm0Ley__fzNZk2dyAAVjNA2QSzTZJc33MQx1pQ",
"e": "AQAB",
"x5t": "-qC0akuyiHT7GcV5a8O5nrFsKVWM9da7lzq6DLrj09I",
"alg": "RS256",
"kty": "RSA"
}
]
})";
auto jwks = jwt::parse_jwks(public_key);
ASSERT_TRUE(jwks.has_jwk("internal-gateway-jwt"));
ASSERT_FALSE(jwks.has_jwk("random-jwt"));
auto jwk = jwks.get_jwk("internal-gateway-jwt");
ASSERT_TRUE(jwk.has_algorithm());
ASSERT_THROW(jwk.get_x5c(), jwt::error::claim_not_present_exception);
auto jwk2 = jwks.get_jwk("internal-0");
ASSERT_EQ(jwk2.get_x5c().size(), 0);
ASSERT_THROW(jwk2.get_x5c_key_value(), jwt::error::claim_not_present_exception);
auto jwk3 = jwks.get_jwk("internal-1");
ASSERT_EQ(jwk3.get_x5c().size(), 3);
ASSERT_EQ(jwk3.get_x5c_key_value(), "1");
}
-220
View File
@@ -1,220 +0,0 @@
#include <string>
namespace test_keys {
std::string rsa_priv_key = R"(-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC4ZtdaIrd1BPIJ
tfnF0TjIK5inQAXZ3XlCrUlJdP+XHwIRxdv1FsN12XyMYO/6ymLmo9ryoQeIrsXB
XYqlET3zfAY+diwCb0HEsVvhisthwMU4gZQu6TYW2s9LnXZB5rVtcBK69hcSlA2k
ZudMZWxZcj0L7KMfO2rIvaHw/qaVOE9j0T257Z8Kp2CLF9MUgX0ObhIsdumFRLaL
DvDUmBPr2zuh/34j2XmWwn1yjN/WvGtdfhXW79Ki1S40HcWnygHgLV8sESFKUxxQ
mKvPUTwDOIwLFL5WtE8Mz7N++kgmDcmWMCHc8kcOIu73Ta/3D4imW7VbKgHZo9+K
3ESFE3RjAgMBAAECggEBAJTEIyjMqUT24G2FKiS1TiHvShBkTlQdoR5xvpZMlYbN
tVWxUmrAGqCQ/TIjYnfpnzCDMLhdwT48Ab6mQJw69MfiXwc1PvwX1e9hRscGul36
ryGPKIVQEBsQG/zc4/L2tZe8ut+qeaK7XuYrPp8bk/X1e9qK5m7j+JpKosNSLgJj
NIbYsBkG2Mlq671irKYj2hVZeaBQmWmZxK4fw0Istz2WfN5nUKUeJhTwpR+JLUg4
ELYYoB7EO0Cej9UBG30hbgu4RyXA+VbptJ+H042K5QJROUbtnLWuuWosZ5ATldwO
u03dIXL0SH0ao5NcWBzxU4F2sBXZRGP2x/jiSLHcqoECgYEA4qD7mXQpu1b8XO8U
6abpKloJCatSAHzjgdR2eRDRx5PMvloipfwqA77pnbjTUFajqWQgOXsDTCjcdQui
wf5XAaWu+TeAVTytLQbSiTsBhrnoqVrr3RoyDQmdnwHT8aCMouOgcC5thP9vQ8Us
rVdjvRRbnJpg3BeSNimH+u9AHgsCgYEA0EzcbOltCWPHRAY7B3Ge/AKBjBQr86Kv
TdpTlxePBDVIlH+BM6oct2gaSZZoHbqPjbq5v7yf0fKVcXE4bSVgqfDJ/sZQu9Lp
PTeV7wkk0OsAMKk7QukEpPno5q6tOTNnFecpUhVLLlqbfqkB2baYYwLJR3IRzboJ
FQbLY93E8gkCgYB+zlC5VlQbbNqcLXJoImqItgQkkuW5PCgYdwcrSov2ve5r/Acz
FNt1aRdSlx4176R3nXyibQA1Vw+ztiUFowiP9WLoM3PtPZwwe4bGHmwGNHPIfwVG
m+exf9XgKKespYbLhc45tuC08DATnXoYK7O1EnUINSFJRS8cezSI5eHcbQKBgQDC
PgqHXZ2aVftqCc1eAaxaIRQhRmY+CgUjumaczRFGwVFveP9I6Gdi+Kca3DE3F9Pq
PKgejo0SwP5vDT+rOGHN14bmGJUMsX9i4MTmZUZ5s8s3lXh3ysfT+GAhTd6nKrIE
kM3Nh6HWFhROptfc6BNusRh1kX/cspDplK5x8EpJ0QKBgQDWFg6S2je0KtbV5PYe
RultUEe2C0jYMDQx+JYxbPmtcopvZQrFEur3WKVuLy5UAy7EBvwMnZwIG7OOohJb
vkSpADK6VPn9lbqq7O8cTedEHttm6otmLt8ZyEl3hZMaL3hbuRj6ysjmoFKx6CrX
rK0/Ikt5ybqUzKCMJZg2VKGTxg==
-----END PRIVATE KEY-----)";
std::string rsa_pub_key = R"(-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuGbXWiK3dQTyCbX5xdE4
yCuYp0AF2d15Qq1JSXT/lx8CEcXb9RbDddl8jGDv+spi5qPa8qEHiK7FwV2KpRE9
83wGPnYsAm9BxLFb4YrLYcDFOIGULuk2FtrPS512Qea1bXASuvYXEpQNpGbnTGVs
WXI9C+yjHztqyL2h8P6mlThPY9E9ue2fCqdgixfTFIF9Dm4SLHbphUS2iw7w1JgT
69s7of9+I9l5lsJ9cozf1rxrXX4V1u/SotUuNB3Fp8oB4C1fLBEhSlMcUJirz1E8
AziMCxS+VrRPDM+zfvpIJg3JljAh3PJHDiLu902v9w+Iplu1WyoB2aPfitxEhRN0
YwIDAQAB
-----END PUBLIC KEY-----)";
std::string rsa_pub_key_invalid = R"(-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxzYuc22QSst/dS7geYYK
5l5kLxU0tayNdixkEQ17ix+CUcUbKIsnyftZxaCYT46rQtXgCaYRdJcbB3hmyrOa
vkhTpX79xJZnQmfuamMbZBqitvscxW9zRR9tBUL6vdi/0rpoUwPMEh8+Bw7CgYR0
FK0DhWYBNDfe9HKcyZEv3max8Cdq18htxjEsdYO0iwzhtKRXomBWTdhD5ykd/fAC
VTr4+KEY+IeLvubHVmLUhbE5NgWXxrRpGasDqzKhCTmsa2Ysf712rl57SlH0Wz/M
r3F7aM9YpErzeYLrl0GhQr9BVJxOvXcVd4kmY+XkiCcrkyS1cnghnllh+LCwQu1s
YwIDAQAB
-----END PUBLIC KEY-----)";
std::string rsa512_priv_key = R"(-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQDdlatRjRjogo3WojgGHFHYLugdUWAY9iR3fy4arWNA1KoS8kVw
33cJibXr8bvwUAUparCwlvdbH6dvEOfou0/gCFQsHUfQrSDv+MuSUMAe8jzKE4qW
+jK+xQU9a03GUnKHkkle+Q0pX/g6jXZ7r1/xAK5Do2kQ+X5xK9cipRgEKwIDAQAB
AoGAD+onAtVye4ic7VR7V50DF9bOnwRwNXrARcDhq9LWNRrRGElESYYTQ6EbatXS
3MCyjjX2eMhu/aF5YhXBwkppwxg+EOmXeh+MzL7Zh284OuPbkglAaGhV9bb6/5Cp
uGb1esyPbYW+Ty2PC0GSZfIXkXs76jXAu9TOBvD0ybc2YlkCQQDywg2R/7t3Q2OE
2+yo382CLJdrlSLVROWKwb4tb2PjhY4XAwV8d1vy0RenxTB+K5Mu57uVSTHtrMK0
GAtFr833AkEA6avx20OHo61Yela/4k5kQDtjEf1N0LfI+BcWZtxsS3jDM3i1Hp0K
Su5rsCPb8acJo5RO26gGVrfAsDcIXKC+bQJAZZ2XIpsitLyPpuiMOvBbzPavd4gY
6Z8KWrfYzJoI/Q9FuBo6rKwl4BFoToD7WIUS+hpkagwWiz+6zLoX1dbOZwJACmH5
fSSjAkLRi54PKJ8TFUeOP15h9sQzydI8zJU+upvDEKZsZc/UhT/SySDOxQ4G/523
Y0sz/OZtSWcol/UMgQJALesy++GdvoIDLfJX5GBQpuFgFenRiRDabxrE9MNUZ2aP
FaFp+DyAe+b4nDwuJaW2LURbr8AEZga7oQj0uYxcYw==
-----END RSA PRIVATE KEY-----)";
std::string rsa512_pub_key = R"(-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDdlatRjRjogo3WojgGHFHYLugd
UWAY9iR3fy4arWNA1KoS8kVw33cJibXr8bvwUAUparCwlvdbH6dvEOfou0/gCFQs
HUfQrSDv+MuSUMAe8jzKE4qW+jK+xQU9a03GUnKHkkle+Q0pX/g6jXZ7r1/xAK5D
o2kQ+X5xK9cipRgEKwIDAQAB
-----END PUBLIC KEY-----)";
std::string rsa512_pub_key_invalid = R"(-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxzYuc22QSst/dS7geYYK
5l5kLxU0tayNdixkEQ17ix+CUcUbKIsnyftZxaCYT46rQtXgCaYRdJcbB3hmyrOa
vkhTpX79xJZnQmfuamMbZBqitvscxW9zRR9tBUL6vdi/0rpoUwPMEh8+Bw7CgYR0
FK0DhWYBNDfe9HKcyZEv3max8Cdq18htxjEsdYO0iwzhtKRXomBWTdhD5ykd/fAC
VTr4+KEY+IeLvubHVmLUhbE5NgWXxrRpGasDqzKhCTmsa2Ysf712rl57SlH0Wz/M
r3F7aM9YpErzeYLrl0GhQr9BVJxOvXcVd4kmY+XkiCcrkyS1cnghnllh+LCwQu1s
YwIDAQAB
-----END PUBLIC KEY-----)";
std::string ecdsa521_priv_key = R"(-----BEGIN EC PRIVATE KEY-----
MIHcAgEBBEIAuZxTZjLIZM5hxgZX+JRrqt5FKpAEg/meZ7m9aSE3XbRITqtfz1Uy
h2Srn7o8+4j/jQpwHTTHZThy10u5jMjaR+mgBwYFK4EEACOhgYkDgYYABAFFah0k
6m4ddp/tUN/ObrKKwSCp4QUZdiAMaC9eY1HyNBPuuEsH5qCfeY5lmeJwSUpzCosn
rgW8M2hQ4Kr5V9OXrgHLA5WVtH6//sSkUY2/xYuqc7/Ln8gI5ddtr1qG64Xtgs05
/CNajSjFZeLm76llakvYiBTTH/ii8hIfrwukW9IP7Q==
-----END EC PRIVATE KEY-----)";
std::string ecdsa521_pub_key = R"(-----BEGIN PUBLIC KEY-----
MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBRWodJOpuHXaf7VDfzm6yisEgqeEF
GXYgDGgvXmNR8jQT7rhLB+agn3mOZZnicElKcwqLJ64FvDNoUOCq+VfTl64BywOV
lbR+v/7EpFGNv8WLqnO/y5/ICOXXba9ahuuF7YLNOfwjWo0oxWXi5u+pZWpL2IgU
0x/4ovISH68LpFvSD+0=
-----END PUBLIC KEY-----)";
std::string ecdsa521_pub_key_invalid = R"(-----BEGIN PUBLIC KEY-----
MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQB3l84szH3VOII+Qp4TGgRqCps1q7N
/41ucX90sVKT+6Z2FgYqGsfDcViWBdcjRQLL69LGApcvGGSa1MiYXmLWBYAAKriR
7S63iNLzarnq1WnCH+GowDMl127CPoSW4LmMqV5rJLJQNwfiy+N0wph/Adnqqb+6
w1N7aVXutqCx02T/jrQ=
-----END PUBLIC KEY-----)";
std::string ecdsa384_priv_key = R"(-----BEGIN EC PRIVATE KEY-----
MIGkAgEBBDCrPXJDgQDtNRpM0qNUW/zN1vrCvOVH1CsItVZ+1NeGB+w/2whnIXJQ
K7U5C1ETPHagBwYFK4EEACKhZANiAAR0JjvVJXc3u1I/7vt5mxzPtAIi1VIqxCwN
wgISZVySTYZQzyicW2GfhMlFCow28LzqTwH/eCymAvnTAmpK/P1hXhNcnxDBZNOU
WMbMLFcQrg2wwpIb/k/IXobNwjNPRBo=
-----END EC PRIVATE KEY-----)";
std::string ecdsa384_pub_key = R"(-----BEGIN PUBLIC KEY-----
MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEdCY71SV3N7tSP+77eZscz7QCItVSKsQs
DcICEmVckk2GUM8onFthn4TJRQqMNvC86k8B/3gspgL50wJqSvz9YV4TXJ8QwWTT
lFjGzCxXEK4NsMKSG/5PyF6GzcIzT0Qa
-----END PUBLIC KEY-----)";
std::string ecdsa384_pub_key_invalid = R"(-----BEGIN PUBLIC KEY-----
MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE7TAJMuqdY9JYXrv2p06bXhLmRddkCQZ6
4BJeTNGz59QqbHk5+6avGj2lXK+c9rr0vejbts5A50WF1E4b7ItLxEIONfSbF74Q
sQ4dg7kzXiz+XX/aEVqH1HlIa9YAJPaH
-----END PUBLIC KEY-----)";
std::string ecdsa256_priv_key = R"(-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgPGJGAm4X1fvBuC1z
SpO/4Izx6PXfNMaiKaS5RUkFqEGhRANCAARCBvmeksd3QGTrVs2eMrrfa7CYF+sX
sjyGg+Bo5mPKGH4Gs8M7oIvoP9pb/I85tdebtKlmiCZHAZE5w4DfJSV6
-----END PRIVATE KEY-----)";
std::string ecdsa256_pub_key = R"(-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEQgb5npLHd0Bk61bNnjK632uwmBfr
F7I8hoPgaOZjyhh+BrPDO6CL6D/aW/yPObXXm7SpZogmRwGROcOA3yUleg==
-----END PUBLIC KEY-----)";
std::string ecdsa256_pub_key_invalid = R"(-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEoBUyo8CQAFPeYPvv78ylh5MwFZjT
CLQeb042TjiMJxG+9DLFmRSMlBQ9T/RsLLc+PmpB1+7yPAR+oR5gZn3kJQ==
-----END PUBLIC KEY-----)";
std::string ecdsa256_certificate = R"(-----BEGIN CERTIFICATE-----
MIIB3zCCAYWgAwIBAgIUXns6sbspahSWU4TRQssO3NLmDr0wCgYIKoZIzj0EAwIw
RTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGElu
dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMDA3MjAyMTA4NTlaFw0yMTA3MjAy
MTA4NTlaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYD
VQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjO
PQMBBwNCAASa+WuX0TojwP3IFXEKO/9vHM+h1YBqTFY1wVGitOZewLxgXgCA8Mlu
yubQaTjyu/2XMAUmcbPwddiUidU4P5OJo1MwUTAdBgNVHQ4EFgQUz9J272oD2ple
bwxJWJ5IFTxFfTowHwYDVR0jBBgwFoAUz9J272oD2plebwxJWJ5IFTxFfTowDwYD
VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgNIADBFAiEAv2rcDBD4p/UeJIEFOK9j
o4XKKbXs6oqMpkEDUinf6DACIGPcShH4m5haelZleORWM068C3BSVToRMSAivE79
8ZhX
-----END CERTIFICATE-----)";
std::string ed25519_priv_key = R"(-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEIP7pYCi8Xipwjttw6ehj0PNrsg3K1Vc5RBqAG5JePqsm
-----END PRIVATE KEY-----)";
std::string ed25519_pub_key = R"(-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEAJHsGwkQLdwqaqp2Ar39YtLCVHiWgUPcGwQfes2cUOEc=
-----END PUBLIC KEY-----)";
std::string ed25519_pub_key_invalid = R"(-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEAJHsGwkQLdwqaqp2Ar39YtLCVHIwGupcGwQfes2cUOEc=
-----END PUBLIC KEY-----)";
std::string ed25519_certificate = R"(-----BEGIN CERTIFICATE-----
MIIBjzCCAUECFCQlWQxMEMe4c3OOimH4/y+o/HpfMAUGAytlcDBqMQswCQYDVQQG
EwJDQTEPMA0GA1UECAwGUXVlYmVjMREwDwYDVQQHDAhNb250cmVhbDEQMA4GA1UE
CgwHand0LWNwcDEPMA0GA1UECwwGZ2l0aHViMRQwEgYDVQQDDAtleGFtcGxlLmNv
bTAeFw0yMDA3MzAyMTIwMDBaFw0yMjA2MzAyMTIwMDBaMGoxCzAJBgNVBAYTAkNB
MQ8wDQYDVQQIDAZRdWViZWMxETAPBgNVBAcMCE1vbnRyZWFsMRAwDgYDVQQKDAdq
d3QtY3BwMQ8wDQYDVQQLDAZnaXRodWIxFDASBgNVBAMMC2V4YW1wbGUuY29tMCow
BQYDK2VwAyEAUdLe1SUWxc/95f39pfmuwe1SLHpFXf5gcRQlMH2sjgwwBQYDK2Vw
A0EAezYcLIUnyy86uUnAZdAMPn7wTruNKtG36GrTF3PF4dtdoGF1OV5DLnNK0Hbs
3GyYtaZs6AEHwDXl/INXu2zoCQ==
-----END CERTIFICATE-----)";
std::string ed448_priv_key = R"(-----BEGIN PRIVATE KEY-----
MEcCAQAwBQYDK2VxBDsEOZNyV4kIWehIWSsPCnDEZbBF+g2WoUgUwox8eQJTq8Hz
y4okU+JZAV8RqQ270fJL/Safvvc1SbbF1A==
-----END PRIVATE KEY-----)";
std::string ed448_pub_key = R"(-----BEGIN PUBLIC KEY-----
MEMwBQYDK2VxAzoAQomzAH8FXc0rhznaLR9DYwe5+DNhP0UwpZzS5y6iJ/iirrzI
9/Fjbc/UvFxwFKFw8IJ9QUwFsE8A
-----END PUBLIC KEY-----)";
std::string ed448_pub_key_invalid = R"(-----BEGIN PUBLIC KEY-----
MEMwBQYDK2VxAzoAQomzAH8FXc0rhznaLR9DYwe5+DNhP0UwpZzS5y6iJ/iirrzI
9/Fjbc/UvFxwFKFW7ij8QUwFsE8A
-----END PUBLIC KEY-----)";
std::string sample_cert = R"(-----BEGIN CERTIFICATE-----
MIIDHDCCAgSgAwIBAgIIGlbUz5cvweUwDQYJKoZIhvcNAQEFBQAwMTEvMC0GA1UE
AxMmc2VjdXJldG9rZW4uc3lzdGVtLmdzZXJ2aWNlYWNjb3VudC5jb20wHhcNMTkw
NDEwMjEyMDUxWhcNMTkwNDI3MDkzNTUxWjAxMS8wLQYDVQQDEyZzZWN1cmV0b2tl
bi5zeXN0ZW0uZ3NlcnZpY2VhY2NvdW50LmNvbTCCASIwDQYJKoZIhvcNAQEBBQAD
ggEPADCCAQoCggEBALRPFSsUi/bGcMVkD+XjJ6z/71u+7Wn1C1bRnM9sU3q7+Ere
DV6an+z+YsjblskBX73h1GyYvmtkyuL7Uq0N+y+RTOmd2fwDw48gM5FEq6DNpVVW
ZRIzzoMSLZCB+tg1eQZdGKtmctdd5Jjhwihf9Aa759fcj60GDG39G6A/w4Jok+J6
7sRabxxontJ4Kpo6zmwUKbWF8naJeCRTO0VAYLkJqEWO4VJTIHJeu2WpxM0qzvY9
IY5Yd7Njegu64FoHU55dSfee2KwDa0/bajrknJfxWBN4hk/rqgGjxQmzAYMCB7/p
/9Snfg4NmfX5cJJ01SNzY6Q/mJRjB3iX2PBz+GsCAwEAAaM4MDYwDAYDVR0TAQH/
BAIwADAOBgNVHQ8BAf8EBAMCB4AwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwIwDQYJ
KoZIhvcNAQEFBQADggEBAKCSq0D+NIAsGULZrhXouurxInxDyq03xLNcxvKDQchc
XfGA1r3eltmlyKQb5TmAsuKwS/LAQ5z8SlRTOmDGVEtDwnw3S83C4ufXbP0eMB6H
eKf2XCA00T3odUfXmQZme8hG6z7GKVOdn/0oY+vaX38brlCpRXDTm1WldyddUpMz
ftcs6dibdnbQtbX6o9E+KuvGHoNW5xcSjX8lwXTpopfvufPOLPcnFXi4UoYZ8NZ2
2mRG78LkOA+SkOMutbt6w7TBDvADmFzuzvAULy4gsfcamOYcQ7uiHnnD+PoNiNbw
flE/m/0zymX8I/Xu3+KKLhUnUROGC6zO3OnLHXCnEns=
-----END CERTIFICATE-----
)";
std::string sample_cert_base64_der = "MIIDHDCCAgSgAwIBAgIIGlbUz5cvweUwDQYJKoZIhvcNAQEFBQAwMTEvMC0GA1UE"
"AxMmc2VjdXJldG9rZW4uc3lzdGVtLmdzZXJ2aWNlYWNjb3VudC5jb20wHhcNMTkw"
"NDEwMjEyMDUxWhcNMTkwNDI3MDkzNTUxWjAxMS8wLQYDVQQDEyZzZWN1cmV0b2tl"
"bi5zeXN0ZW0uZ3NlcnZpY2VhY2NvdW50LmNvbTCCASIwDQYJKoZIhvcNAQEBBQAD"
"ggEPADCCAQoCggEBALRPFSsUi/bGcMVkD+XjJ6z/71u+7Wn1C1bRnM9sU3q7+Ere"
"DV6an+z+YsjblskBX73h1GyYvmtkyuL7Uq0N+y+RTOmd2fwDw48gM5FEq6DNpVVW"
"ZRIzzoMSLZCB+tg1eQZdGKtmctdd5Jjhwihf9Aa759fcj60GDG39G6A/w4Jok+J6"
"7sRabxxontJ4Kpo6zmwUKbWF8naJeCRTO0VAYLkJqEWO4VJTIHJeu2WpxM0qzvY9"
"IY5Yd7Njegu64FoHU55dSfee2KwDa0/bajrknJfxWBN4hk/rqgGjxQmzAYMCB7/p"
"/9Snfg4NmfX5cJJ01SNzY6Q/mJRjB3iX2PBz+GsCAwEAAaM4MDYwDAYDVR0TAQH/"
"BAIwADAOBgNVHQ8BAf8EBAMCB4AwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwIwDQYJ"
"KoZIhvcNAQEFBQADggEBAKCSq0D+NIAsGULZrhXouurxInxDyq03xLNcxvKDQchc"
"XfGA1r3eltmlyKQb5TmAsuKwS/LAQ5z8SlRTOmDGVEtDwnw3S83C4ufXbP0eMB6H"
"eKf2XCA00T3odUfXmQZme8hG6z7GKVOdn/0oY+vaX38brlCpRXDTm1WldyddUpMz"
"ftcs6dibdnbQtbX6o9E+KuvGHoNW5xcSjX8lwXTpopfvufPOLPcnFXi4UoYZ8NZ2"
"2mRG78LkOA+SkOMutbt6w7TBDvADmFzuzvAULy4gsfcamOYcQ7uiHnnD+PoNiNbw"
"flE/m/0zymX8I/Xu3+KKLhUnUROGC6zO3OnLHXCnEns=";
std::string sample_cert_pubkey = R"(-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtE8VKxSL9sZwxWQP5eMn
rP/vW77tafULVtGcz2xTerv4St4NXpqf7P5iyNuWyQFfveHUbJi+a2TK4vtSrQ37
L5FM6Z3Z/APDjyAzkUSroM2lVVZlEjPOgxItkIH62DV5Bl0Yq2Zy113kmOHCKF/0
Brvn19yPrQYMbf0boD/DgmiT4nruxFpvHGie0ngqmjrObBQptYXydol4JFM7RUBg
uQmoRY7hUlMgcl67ZanEzSrO9j0hjlh3s2N6C7rgWgdTnl1J957YrANrT9tqOuSc
l/FYE3iGT+uqAaPFCbMBgwIHv+n/1Kd+Dg2Z9flwknTVI3NjpD+YlGMHeJfY8HP4
awIDAQAB
-----END PUBLIC KEY-----
)";
} // namespace test_keys
@@ -1,931 +0,0 @@
#ifdef __linux__ // None of this stuff is going to work outside of linux!
#ifndef HUNTER_ENABLED // Static linking (which hunter always? does) breaks the tests (duplicate definition), so skip them
#include "jwt-cpp/jwt.h"
#include <gtest/gtest.h>
#include <dlfcn.h>
// TODO: Figure out why the tests fail on older openssl versions
#ifndef JWT_OPENSSL_1_0_0 // It fails on < 1.1 but no idea why.
// LibreSSL has different return codes but was already outside of the effective scope
/**
* ============ Beginning of black magic ===============
* We mock out a couple of openssl functions.
* We can do this because the current executable take precedence while linking.
* Once it is running and we want normal behaviour, we query the original method using dlsym.
*/
static uint64_t fail_BIO_new = 0;
static uint64_t fail_PEM_read_bio_X509 = 0;
static uint64_t fail_X509_get_pubkey = 0;
static uint64_t fail_PEM_write_bio_PUBKEY = 0;
static uint64_t fail_PEM_write_bio_cert = 0;
static uint64_t fail_BIO_ctrl = 0;
static uint64_t fail_BIO_write = 0;
static uint64_t fail_PEM_read_bio_PUBKEY = 0;
static uint64_t fail_PEM_read_bio_PrivateKey = 0;
static uint64_t fail_HMAC = 0;
static uint64_t fail_EVP_MD_CTX_new = 0;
static uint64_t fail_EVP_DigestInit = 0;
static uint64_t fail_EVP_DigestUpdate = 0;
static uint64_t fail_EVP_DigestFinal = 0;
static uint64_t fail_EVP_SignFinal = 0;
static uint64_t fail_EVP_VerifyFinal = 0;
#ifdef JWT_OPENSSL_3_0
static uint64_t fail_EVP_PKEY_public_check = 0;
static uint64_t fail_EVP_PKEY_private_check = 0;
static uint64_t fail_EVP_PKEY_CTX_new_from_pkey = 0;
#else
static uint64_t fail_EC_KEY_check_key = 0;
static uint64_t fail_EVP_PKEY_get1_EC_KEY = 0;
#endif
static uint64_t fail_ECDSA_SIG_new = 0;
static uint64_t fail_EVP_PKEY_get1_RSA = 0;
static uint64_t fail_EVP_DigestSignInit = 0;
static uint64_t fail_EVP_DigestSign = 0;
static uint64_t fail_EVP_DigestVerifyInit = 0;
static uint64_t fail_EVP_DigestVerify = 0;
static uint64_t fail_EVP_DigestSignFinal = 0;
static uint64_t fail_EVP_DigestVerifyFinal = 0;
static uint64_t fail_d2i_ECDSA_SIG = 0;
static uint64_t fail_i2d_ECDSA_SIG = 0;
BIO* BIO_new(const BIO_METHOD* type) {
static BIO* (*origMethod)(const BIO_METHOD*) = nullptr;
if (origMethod == nullptr) origMethod = (decltype(origMethod))dlsym(RTLD_NEXT, "BIO_new");
bool fail = fail_BIO_new & 1;
fail_BIO_new = fail_BIO_new >> 1;
if (fail)
return nullptr;
else
return origMethod(type);
}
X509* PEM_read_bio_X509(BIO* bp, X509** x, pem_password_cb* cb, void* u) {
static X509* (*origMethod)(BIO * bp, X509 * *x, pem_password_cb * cb, void* u) = nullptr;
if (origMethod == nullptr) origMethod = (decltype(origMethod))dlsym(RTLD_NEXT, "PEM_read_bio_X509");
bool fail = fail_PEM_read_bio_X509 & 1;
fail_PEM_read_bio_X509 = fail_PEM_read_bio_X509 >> 1;
if (fail)
return nullptr;
else
return origMethod(bp, x, cb, u);
}
EVP_PKEY* X509_get_pubkey(X509* x) {
static EVP_PKEY* (*origMethod)(X509*) = nullptr;
if (origMethod == nullptr) origMethod = (decltype(origMethod))dlsym(RTLD_NEXT, "X509_get_pubkey");
bool fail = fail_X509_get_pubkey & 1;
fail_X509_get_pubkey = fail_X509_get_pubkey >> 1;
if (fail)
return nullptr;
else
return origMethod(x);
}
#ifdef JWT_OPENSSL_3_0
#define OPENSSL_CONST const
#else
#define OPENSSL_CONST
#endif
int PEM_write_bio_PUBKEY(BIO* bp, OPENSSL_CONST EVP_PKEY* x) {
static int (*origMethod)(BIO * bp, OPENSSL_CONST EVP_PKEY * x) = nullptr;
if (origMethod == nullptr) origMethod = (decltype(origMethod))dlsym(RTLD_NEXT, "PEM_write_bio_PUBKEY");
bool fail = fail_PEM_write_bio_PUBKEY & 1;
fail_PEM_write_bio_PUBKEY = fail_PEM_write_bio_PUBKEY >> 1;
if (fail)
return 0;
else
return origMethod(bp, x);
}
int PEM_write_bio_X509(BIO* bp, OPENSSL_CONST X509* x) {
static int (*origMethod)(BIO * bp, OPENSSL_CONST X509 * x) = nullptr;
if (origMethod == nullptr) origMethod = (decltype(origMethod))dlsym(RTLD_NEXT, "PEM_write_bio_X509");
bool fail = fail_PEM_write_bio_cert & 1;
fail_PEM_write_bio_cert = fail_PEM_write_bio_cert >> 1;
if (fail)
return 0;
else
return origMethod(bp, x);
}
long BIO_ctrl(BIO* bp, int cmd, long larg, void* parg) {
static long (*origMethod)(BIO * bp, int cmd, long larg, void* parg) = nullptr;
if (origMethod == nullptr) origMethod = (decltype(origMethod))dlsym(RTLD_NEXT, "BIO_ctrl");
bool fail = fail_BIO_ctrl & 1;
fail_BIO_ctrl = fail_BIO_ctrl >> 1;
if (fail)
return 0;
else
return origMethod(bp, cmd, larg, parg);
}
int BIO_write(BIO* b, const void* data, int dlen) {
static int (*origMethod)(BIO * b, const void* data, int dlen) = nullptr;
if (origMethod == nullptr) origMethod = (decltype(origMethod))dlsym(RTLD_NEXT, "BIO_write");
bool fail = fail_BIO_write & 1;
fail_BIO_write = fail_BIO_write >> 1;
if (fail)
return 0;
else
return origMethod(b, data, dlen);
}
EVP_PKEY* PEM_read_bio_PUBKEY(BIO* bp, EVP_PKEY** x, pem_password_cb* cb, void* u) {
static EVP_PKEY* (*origMethod)(BIO * bp, EVP_PKEY * *x, pem_password_cb * cb, void* u) = nullptr;
if (origMethod == nullptr) origMethod = (decltype(origMethod))dlsym(RTLD_NEXT, "PEM_read_bio_PUBKEY");
bool fail = fail_PEM_read_bio_PUBKEY & 1;
fail_PEM_read_bio_PUBKEY = fail_PEM_read_bio_PUBKEY >> 1;
if (fail)
return nullptr;
else
return origMethod(bp, x, cb, u);
}
EVP_PKEY* PEM_read_bio_PrivateKey(BIO* bp, EVP_PKEY** x, pem_password_cb* cb, void* u) {
static EVP_PKEY* (*origMethod)(BIO * bp, EVP_PKEY * *x, pem_password_cb * cb, void* u) = nullptr;
if (origMethod == nullptr) origMethod = (decltype(origMethod))dlsym(RTLD_NEXT, "PEM_read_bio_PrivateKey");
bool fail = fail_PEM_read_bio_PrivateKey & 1;
fail_PEM_read_bio_PrivateKey = fail_PEM_read_bio_PrivateKey >> 1;
if (fail)
return nullptr;
else
return origMethod(bp, x, cb, u);
}
unsigned char* HMAC(const EVP_MD* evp_md, const void* key, int key_len, const unsigned char* d, size_t n,
unsigned char* md, unsigned int* md_len) {
static unsigned char* (*origMethod)(const EVP_MD* evp_md, const void* key, int key_len, const unsigned char* d,
size_t n, unsigned char* md, unsigned int* md_len) = nullptr;
if (origMethod == nullptr) origMethod = (decltype(origMethod))dlsym(RTLD_NEXT, "HMAC");
bool fail = fail_HMAC & 1;
fail_HMAC = fail_HMAC >> 1;
if (fail)
return nullptr;
else
return origMethod(evp_md, key, key_len, d, n, md, md_len);
}
EVP_MD_CTX* EVP_MD_CTX_new(void) {
static EVP_MD_CTX* (*origMethod)(void) = nullptr;
if (origMethod == nullptr) origMethod = (decltype(origMethod))dlsym(RTLD_NEXT, "EVP_MD_CTX_new");
bool fail = fail_EVP_MD_CTX_new & 1;
fail_EVP_MD_CTX_new = fail_EVP_MD_CTX_new >> 1;
if (fail)
return nullptr;
else
return origMethod();
}
int EVP_DigestSignFinal(EVP_MD_CTX* ctx, unsigned char* sigret, size_t* siglen) {
static int (*origMethod)(EVP_MD_CTX * ctx, unsigned char* sigret, size_t* siglen) = nullptr;
if (origMethod == nullptr) origMethod = (decltype(origMethod))dlsym(RTLD_NEXT, "EVP_DigestSignFinal");
bool fail = fail_EVP_DigestSignFinal & 1;
fail_EVP_DigestSignFinal = fail_EVP_DigestSignFinal >> 1;
if (fail)
return 0;
else
return origMethod(ctx, sigret, siglen);
}
int EVP_DigestInit(EVP_MD_CTX* ctx, const EVP_MD* type) {
static int (*origMethod)(EVP_MD_CTX * ctx, const EVP_MD* type) = nullptr;
if (origMethod == nullptr) origMethod = (decltype(origMethod))dlsym(RTLD_NEXT, "EVP_DigestInit");
bool fail = fail_EVP_DigestInit & 1;
fail_EVP_DigestInit = fail_EVP_DigestInit >> 1;
if (fail)
return 0;
else
return origMethod(ctx, type);
}
int EVP_DigestUpdate(EVP_MD_CTX* ctx, const void* d, size_t cnt) {
static int (*origMethod)(EVP_MD_CTX * ctx, const void* d, size_t cnt) = nullptr;
if (origMethod == nullptr) origMethod = (decltype(origMethod))dlsym(RTLD_NEXT, "EVP_DigestUpdate");
bool fail = fail_EVP_DigestUpdate & 1;
fail_EVP_DigestUpdate = fail_EVP_DigestUpdate >> 1;
if (fail)
return 0;
else
return origMethod(ctx, d, cnt);
}
int EVP_DigestFinal(EVP_MD_CTX* ctx, unsigned char* md, unsigned int* s) {
static int (*origMethod)(EVP_MD_CTX * ctx, unsigned char* md, unsigned int* s) = nullptr;
if (origMethod == nullptr) origMethod = (decltype(origMethod))dlsym(RTLD_NEXT, "EVP_DigestFinal");
bool fail = fail_EVP_DigestFinal & 1;
fail_EVP_DigestFinal = fail_EVP_DigestFinal >> 1;
if (fail)
return 0;
else
return origMethod(ctx, md, s);
}
int EVP_SignFinal(EVP_MD_CTX* ctx, unsigned char* md, unsigned int* s, EVP_PKEY* pkey) {
static int (*origMethod)(EVP_MD_CTX * ctx, unsigned char* md, unsigned int* s, EVP_PKEY* pkey) = nullptr;
if (origMethod == nullptr) origMethod = (decltype(origMethod))dlsym(RTLD_NEXT, "EVP_SignFinal");
bool fail = fail_EVP_SignFinal & 1;
fail_EVP_SignFinal = fail_EVP_SignFinal >> 1;
if (fail)
return 0;
else
return origMethod(ctx, md, s, pkey);
}
int EVP_VerifyFinal(EVP_MD_CTX* ctx, const unsigned char* sigbuf, unsigned int siglen, EVP_PKEY* pkey) {
static int (*origMethod)(EVP_MD_CTX * ctx, const unsigned char* sigbuf, unsigned int siglen, EVP_PKEY* pkey) =
nullptr;
if (origMethod == nullptr) origMethod = (decltype(origMethod))dlsym(RTLD_NEXT, "EVP_VerifyFinal");
bool fail = fail_EVP_VerifyFinal & 1;
fail_EVP_VerifyFinal = fail_EVP_VerifyFinal >> 1;
if (fail)
return 0;
else
return origMethod(ctx, sigbuf, siglen, pkey);
}
#ifdef JWT_OPENSSL_3_0
int EVP_PKEY_public_check(EVP_PKEY_CTX* ctx) {
static int (*origMethod)(EVP_PKEY_CTX * ctx) = nullptr;
if (origMethod == nullptr) origMethod = (decltype(origMethod))dlsym(RTLD_NEXT, "EVP_PKEY_public_check");
bool fail = fail_EVP_PKEY_public_check & 1;
fail_EVP_PKEY_public_check = fail_EVP_PKEY_public_check >> 1;
if (fail)
return 0;
else
return origMethod(ctx);
}
int EVP_PKEY_private_check(EVP_PKEY_CTX* ctx) {
static int (*origMethod)(EVP_PKEY_CTX * ctx) = nullptr;
if (origMethod == nullptr) origMethod = (decltype(origMethod))dlsym(RTLD_NEXT, "EVP_PKEY_private_check");
bool fail = fail_EVP_PKEY_private_check & 1;
fail_EVP_PKEY_private_check = fail_EVP_PKEY_private_check >> 1;
if (fail)
return 0;
else
return origMethod(ctx);
}
EVP_PKEY_CTX* EVP_PKEY_CTX_new_from_pkey(OSSL_LIB_CTX* libctx, EVP_PKEY* pkey, const char* propquery) {
static EVP_PKEY_CTX* (*origMethod)(OSSL_LIB_CTX * libctx, EVP_PKEY * pkey, const char* propquery) = nullptr;
if (origMethod == nullptr) origMethod = (decltype(origMethod))dlsym(RTLD_NEXT, "EVP_PKEY_CTX_new_from_pkey");
bool fail = fail_EVP_PKEY_CTX_new_from_pkey & 1;
fail_EVP_PKEY_CTX_new_from_pkey = fail_EVP_PKEY_CTX_new_from_pkey >> 1;
if (fail)
return nullptr;
else
return origMethod(libctx, pkey, propquery);
}
#else
int EC_KEY_check_key(const EC_KEY* key) {
static int (*origMethod)(const EC_KEY* key) = nullptr;
if (origMethod == nullptr) origMethod = (decltype(origMethod))dlsym(RTLD_NEXT, "EC_KEY_check_key");
bool fail = fail_EC_KEY_check_key & 1;
fail_EC_KEY_check_key = fail_EC_KEY_check_key >> 1;
if (fail)
return 0;
else
return origMethod(key);
}
EC_KEY* EVP_PKEY_get1_EC_KEY(EVP_PKEY* pkey) {
static EC_KEY* (*origMethod)(EVP_PKEY * pkey) = nullptr;
if (origMethod == nullptr) origMethod = (decltype(origMethod))dlsym(RTLD_NEXT, "EVP_PKEY_get1_EC_KEY");
bool fail = fail_EVP_PKEY_get1_EC_KEY & 1;
fail_EVP_PKEY_get1_EC_KEY = fail_EVP_PKEY_get1_EC_KEY >> 1;
if (fail)
return nullptr;
else
return origMethod(pkey);
}
#endif
ECDSA_SIG* ECDSA_SIG_new(void) {
static ECDSA_SIG* (*origMethod)() = nullptr;
if (origMethod == nullptr) origMethod = (decltype(origMethod))dlsym(RTLD_NEXT, "ECDSA_SIG_new");
bool fail = fail_ECDSA_SIG_new & 1;
fail_ECDSA_SIG_new = fail_ECDSA_SIG_new >> 1;
if (fail)
return nullptr;
else
return origMethod();
}
struct rsa_st* EVP_PKEY_get1_RSA(EVP_PKEY* pkey) {
static struct rsa_st* (*origMethod)(EVP_PKEY * pkey) = nullptr;
if (origMethod == nullptr) origMethod = (decltype(origMethod))dlsym(RTLD_NEXT, "EVP_PKEY_get1_RSA");
bool fail = fail_EVP_PKEY_get1_RSA & 1;
fail_EVP_PKEY_get1_RSA = fail_EVP_PKEY_get1_RSA >> 1;
if (fail)
return nullptr;
else
return origMethod(pkey);
}
int EVP_DigestSignInit(EVP_MD_CTX* ctx, EVP_PKEY_CTX** pctx, const EVP_MD* type, ENGINE* e, EVP_PKEY* pkey) {
static int (*origMethod)(EVP_MD_CTX * ctx, EVP_PKEY_CTX * *pctx, const EVP_MD* type, ENGINE* e, EVP_PKEY* pkey) =
nullptr;
if (origMethod == nullptr) origMethod = (decltype(origMethod))dlsym(RTLD_NEXT, "EVP_DigestSignInit");
bool fail = fail_EVP_DigestSignInit & 1;
fail_EVP_DigestSignInit = fail_EVP_DigestSignInit >> 1;
if (fail)
return 0;
else
return origMethod(ctx, pctx, type, e, pkey);
}
int EVP_DigestSign(EVP_MD_CTX* ctx, unsigned char* sigret, size_t* siglen, const unsigned char* tbs, size_t tbslen) {
static int (*origMethod)(EVP_MD_CTX * ctx, unsigned char* sigret, size_t* siglen, const unsigned char* tbs,
size_t tbslen) = nullptr;
if (origMethod == nullptr) origMethod = (decltype(origMethod))dlsym(RTLD_NEXT, "EVP_DigestSign");
bool fail = fail_EVP_DigestSign & 1;
fail_EVP_DigestSign = fail_EVP_DigestSign >> 1;
if (fail)
return 0;
else
return origMethod(ctx, sigret, siglen, tbs, tbslen);
}
int EVP_DigestVerifyInit(EVP_MD_CTX* ctx, EVP_PKEY_CTX** pctx, const EVP_MD* type, ENGINE* e, EVP_PKEY* pkey) {
static int (*origMethod)(EVP_MD_CTX * ctx, EVP_PKEY_CTX * *pctx, const EVP_MD* type, ENGINE* e, EVP_PKEY* pkey) =
nullptr;
if (origMethod == nullptr) origMethod = (decltype(origMethod))dlsym(RTLD_NEXT, "EVP_DigestVerifyInit");
bool fail = fail_EVP_DigestVerifyInit & 1;
fail_EVP_DigestVerifyInit = fail_EVP_DigestVerifyInit >> 1;
if (fail)
return 0;
else
return origMethod(ctx, pctx, type, e, pkey);
}
int EVP_DigestVerify(EVP_MD_CTX* ctx, unsigned char* sigret, size_t* siglen, const unsigned char* tbs, size_t tbslen) {
static int (*origMethod)(EVP_MD_CTX * ctx, unsigned char* sigret, size_t* siglen, const unsigned char* tbs,
size_t tbslen) = nullptr;
if (origMethod == nullptr) origMethod = (decltype(origMethod))dlsym(RTLD_NEXT, "EVP_DigestVerify");
bool fail = fail_EVP_DigestVerify & 1;
fail_EVP_DigestVerify = fail_EVP_DigestVerify >> 1;
if (fail)
return 0;
else
return origMethod(ctx, sigret, siglen, tbs, tbslen);
}
int EVP_DigestVerifyFinal(EVP_MD_CTX* ctx, const unsigned char* sigret, size_t siglen) {
static int (*origMethod)(EVP_MD_CTX * ctx, const unsigned char* sigret, size_t siglen) = nullptr;
if (origMethod == nullptr) origMethod = (decltype(origMethod))dlsym(RTLD_NEXT, "EVP_DigestVerifyFinal");
bool fail = fail_EVP_DigestVerifyFinal & 1;
fail_EVP_DigestVerifyFinal = fail_EVP_DigestVerifyFinal >> 1;
if (fail)
return 0;
else
return origMethod(ctx, sigret, siglen);
}
int i2d_ECDSA_SIG(const ECDSA_SIG* sig, unsigned char** ppout) {
static int (*origMethod)(const ECDSA_SIG* sig, unsigned char** ppout) = nullptr;
if (origMethod == nullptr) origMethod = (decltype(origMethod))dlsym(RTLD_NEXT, "i2d_ECDSA_SIG");
bool fail = fail_i2d_ECDSA_SIG & 1;
fail_i2d_ECDSA_SIG = fail_i2d_ECDSA_SIG >> 1;
if (fail)
return -1;
else
return origMethod(sig, ppout);
}
ECDSA_SIG* d2i_ECDSA_SIG(ECDSA_SIG** psig, const unsigned char** ppin, long len) {
static ECDSA_SIG* (*origMethod)(ECDSA_SIG * *psig, const unsigned char** ppin, long len) = nullptr;
if (origMethod == nullptr) origMethod = (decltype(origMethod))dlsym(RTLD_NEXT, "d2i_ECDSA_SIG");
bool fail = fail_d2i_ECDSA_SIG & 1;
fail_d2i_ECDSA_SIG = fail_d2i_ECDSA_SIG >> 1;
if (fail)
return nullptr;
else
return origMethod(psig, ppin, len);
}
/**
* =========== End of black magic ============
*/
inline namespace test_keys {
extern std::string rsa_priv_key;
extern std::string rsa_pub_key;
extern std::string rsa_pub_key_invalid;
extern std::string rsa512_priv_key;
extern std::string rsa512_pub_key;
extern std::string rsa512_pub_key_invalid;
extern std::string ecdsa256_certificate;
extern std::string ecdsa256_priv_key;
extern std::string ecdsa256_pub_key;
extern std::string ecdsa256_pub_key_invalid;
extern std::string ecdsa384_priv_key;
extern std::string ecdsa384_pub_key;
extern std::string ecdsa384_pub_key_invalid;
extern std::string ecdsa521_priv_key;
extern std::string ecdsa521_pub_key;
extern std::string ecdsa521_pub_key_invalid;
extern std::string sample_cert;
extern std::string sample_cert_base64_der;
extern std::string sample_cert_pubkey;
extern std::string ed25519_priv_key;
extern std::string ed25519_pub_key;
extern std::string ed25519_pub_key_invalid;
extern std::string ed25519_certificate;
extern std::string ed448_priv_key;
extern std::string ed448_pub_key;
extern std::string ed448_pub_key_invalid;
} // namespace test_keys
TEST(OpenSSLErrorTest, ExtractPubkeyFromCertReference) {
std::error_code ec;
auto res = jwt::helper::extract_pubkey_from_cert(sample_cert, "", ec);
ASSERT_EQ(res, sample_cert_pubkey);
ASSERT_FALSE(!(!ec));
ASSERT_EQ(ec.value(), 0);
}
TEST(OpenSSLErrorTest, ConvertCertBase64DerToPemReference) {
std::error_code ec;
auto res = jwt::helper::convert_base64_der_to_pem(sample_cert_base64_der, ec);
ASSERT_EQ(res, sample_cert);
ASSERT_FALSE(!(!ec));
ASSERT_EQ(ec.value(), 0);
}
struct multitest_entry {
uint64_t* fail_mask_ptr;
uint64_t fail_bitmask;
std::error_code expected_ec;
};
template<typename Func>
void run_multitest(const std::vector<multitest_entry>& mapping, Func fn) {
for (auto& e : mapping) {
std::error_code ec;
*e.fail_mask_ptr = e.fail_bitmask;
try {
fn(ec);
} catch (...) {
*e.fail_mask_ptr = 0;
throw;
}
*e.fail_mask_ptr = 0;
ASSERT_EQ(ec, e.expected_ec);
}
}
TEST(OpenSSLErrorTest, ExtractPubkeyFromCert) {
std::vector<multitest_entry> mapping{{&fail_BIO_new, 1, jwt::error::rsa_error::create_mem_bio_failed},
{&fail_PEM_read_bio_X509, 1, jwt::error::rsa_error::cert_load_failed},
{&fail_X509_get_pubkey, 1, jwt::error::rsa_error::get_key_failed},
{&fail_PEM_write_bio_PUBKEY, 1, jwt::error::rsa_error::write_key_failed},
{&fail_BIO_ctrl, 1, jwt::error::rsa_error::convert_to_pem_failed}};
run_multitest(mapping, [](std::error_code& ec) {
try {
jwt::helper::extract_pubkey_from_cert(sample_cert, "");
FAIL(); // Should never reach this
} catch (const jwt::error::rsa_exception& e) { ec = e.code(); }
});
}
TEST(OpenSSLErrorTest, ExtractPubkeyFromCertErrorCode) {
std::vector<multitest_entry> mapping{{&fail_BIO_new, 1, jwt::error::rsa_error::create_mem_bio_failed},
{&fail_PEM_read_bio_X509, 1, jwt::error::rsa_error::cert_load_failed},
{&fail_X509_get_pubkey, 1, jwt::error::rsa_error::get_key_failed},
{&fail_PEM_write_bio_PUBKEY, 1, jwt::error::rsa_error::write_key_failed},
{&fail_BIO_ctrl, 1, jwt::error::rsa_error::convert_to_pem_failed}};
run_multitest(mapping, [](std::error_code& ec) {
auto res = jwt::helper::extract_pubkey_from_cert(sample_cert, "", ec);
ASSERT_EQ(res, "");
});
}
TEST(OpenSSLErrorTest, ConvertCertBase64DerToPem) {
std::vector<multitest_entry> mapping{{&fail_BIO_new, 1, jwt::error::rsa_error::create_mem_bio_failed},
{&fail_PEM_write_bio_cert, 1, jwt::error::rsa_error::write_cert_failed},
{&fail_BIO_ctrl, 1, jwt::error::rsa_error::convert_to_pem_failed}};
run_multitest(mapping, [](std::error_code& ec) {
try {
jwt::helper::convert_base64_der_to_pem(sample_cert_base64_der);
FAIL(); // Should never reach this
} catch (const jwt::error::rsa_exception& e) { ec = e.code(); }
});
}
TEST(OpenSSLErrorTest, ConvertCertBase64DerToPemErrorCode) {
std::vector<multitest_entry> mapping{{&fail_BIO_new, 1, jwt::error::rsa_error::create_mem_bio_failed},
{&fail_PEM_write_bio_cert, 1, jwt::error::rsa_error::write_cert_failed},
{&fail_BIO_ctrl, 1, jwt::error::rsa_error::convert_to_pem_failed}};
run_multitest(mapping, [](std::error_code& ec) {
auto res = jwt::helper::convert_base64_der_to_pem(sample_cert_base64_der, ec);
ASSERT_EQ(res, "");
});
}
TEST(OpenSSLErrorTest, LoadPublicKeyFromStringReference) {
auto res = jwt::helper::load_public_key_from_string(rsa_pub_key, "");
ASSERT_TRUE(res);
}
TEST(OpenSSLErrorTest, LoadPublicKeyFromString) {
std::vector<multitest_entry> mapping{{&fail_BIO_new, 1, jwt::error::rsa_error::create_mem_bio_failed},
{&fail_BIO_write, 1, jwt::error::rsa_error::load_key_bio_write},
{&fail_PEM_read_bio_PUBKEY, 1, jwt::error::rsa_error::load_key_bio_read}};
run_multitest(mapping, [](std::error_code& ec) {
try {
jwt::helper::load_public_key_from_string(rsa_pub_key, "");
FAIL(); // Should never reach this
} catch (const jwt::error::rsa_exception& e) { ec = e.code(); }
});
}
TEST(OpenSSLErrorTest, LoadPublicKeyFromStringErrorCode) {
std::vector<multitest_entry> mapping{{&fail_BIO_new, 1, jwt::error::rsa_error::create_mem_bio_failed},
{&fail_BIO_write, 1, jwt::error::rsa_error::load_key_bio_write},
{&fail_PEM_read_bio_PUBKEY, 1, jwt::error::rsa_error::load_key_bio_read}};
run_multitest(mapping, [](std::error_code& ec) {
auto res = jwt::helper::load_public_key_from_string(rsa_pub_key, "", ec);
ASSERT_FALSE(res);
});
}
TEST(OpenSSLErrorTest, LoadPublicKeyCertFromStringReference) {
auto res = jwt::helper::load_public_key_from_string(sample_cert, "");
ASSERT_TRUE(res);
}
TEST(OpenSSLErrorTest, LoadPublicKeyCertFromString) {
std::vector<multitest_entry> mapping {
{&fail_BIO_new, 1, jwt::error::rsa_error::create_mem_bio_failed},
#if !defined(LIBRESSL_VERSION_NUMBER) || LIBRESSL_VERSION_NUMBER < 0x3050300fL
{&fail_BIO_write, 1, jwt::error::rsa_error::load_key_bio_write},
#else
{&fail_BIO_write, 1, jwt::error::rsa_error::write_key_failed},
#endif
{
&fail_PEM_read_bio_PUBKEY, 1, jwt::error::rsa_error::load_key_bio_read
}
};
run_multitest(mapping, [](std::error_code& ec) {
try {
jwt::helper::load_public_key_from_string(sample_cert, "");
FAIL(); // Should never reach this
} catch (const jwt::error::rsa_exception& e) { ec = e.code(); }
});
}
TEST(OpenSSLErrorTest, LoadPublicKeyCertFromStringErrorCode) {
std::vector<multitest_entry> mapping {
{&fail_BIO_new, 1, jwt::error::rsa_error::create_mem_bio_failed},
#if !defined(LIBRESSL_VERSION_NUMBER) || LIBRESSL_VERSION_NUMBER < 0x3050300fL
{&fail_BIO_write, 1, jwt::error::rsa_error::load_key_bio_write},
#else
{&fail_BIO_write, 1, jwt::error::rsa_error::write_key_failed},
#endif
{
&fail_PEM_read_bio_PUBKEY, 1, jwt::error::rsa_error::load_key_bio_read
}
};
run_multitest(mapping, [](std::error_code& ec) {
auto res = jwt::helper::load_public_key_from_string(sample_cert, "", ec);
ASSERT_FALSE(res);
});
}
TEST(OpenSSLErrorTest, LoadPrivateKeyFromStringReference) {
auto res = jwt::helper::load_private_key_from_string(rsa_priv_key, "");
ASSERT_TRUE(res);
}
TEST(OpenSSLErrorTest, LoadPrivateKeyFromString) {
std::vector<multitest_entry> mapping{{&fail_BIO_new, 1, jwt::error::rsa_error::create_mem_bio_failed},
{&fail_BIO_write, 1, jwt::error::rsa_error::load_key_bio_write},
{&fail_PEM_read_bio_PrivateKey, 1, jwt::error::rsa_error::load_key_bio_read}};
run_multitest(mapping, [](std::error_code& ec) {
try {
jwt::helper::load_private_key_from_string(rsa_priv_key, "");
FAIL(); // Should never reach this
} catch (const jwt::error::rsa_exception& e) { ec = e.code(); }
});
}
TEST(OpenSSLErrorTest, LoadPrivateKeyFromStringErrorCode) {
std::vector<multitest_entry> mapping{{&fail_BIO_new, 1, jwt::error::rsa_error::create_mem_bio_failed},
{&fail_BIO_write, 1, jwt::error::rsa_error::load_key_bio_write},
{&fail_PEM_read_bio_PrivateKey, 1, jwt::error::rsa_error::load_key_bio_read}};
run_multitest(mapping, [](std::error_code& ec) {
auto res = jwt::helper::load_private_key_from_string(rsa_priv_key, "", ec);
ASSERT_FALSE(res);
});
}
TEST(OpenSSLErrorTest, HMACSign) {
std::string token =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCJ9.AbIJTDMFc7yUa5MhvcP03nJPyCPzZtQcGEp-zWfOkEE";
auto verify = jwt::verify().allow_algorithm(jwt::algorithm::hs256{"secret"}).with_issuer("auth0");
auto decoded_token = jwt::decode(token);
std::vector<multitest_entry> mapping{{&fail_HMAC, 1, jwt::error::signature_generation_error::hmac_failed}};
run_multitest(mapping, [&](std::error_code& ec) { verify.verify(decoded_token, ec); });
}
TEST(OpenSSLErrorTest, RS256Reference) {
jwt::algorithm::rs256 alg{rsa_pub_key, rsa_priv_key};
std::error_code ec;
auto res = alg.sign("testdata", ec);
ASSERT_EQ(jwt::base::encode<jwt::alphabet::base64>(res),
"oCJUeLmIKKVVE/UWhEL/Malx0l9TCoXWNAS2z9o8ZYNaS4POIeadZWeUbLdICx3SCJCnGRwL8JkAmYx1wexT2QGuVXXAtZvRu8ceyuQy"
"AhzGkI9HdADu5YAJsUaLknDUV5hmundXQY8lhwQnKFXW0rl0H8DoFiPQErFmcKI6PA9NVGK/LSiqHqesNeg0wqCTxMmeT6pqI7FH9fDO"
"CaBpwUJ4t5aKoytQ75t13OfUM7tfLlVkFZtI3RndhivxLA5d4Elt/Gv3RhDu6Eiom5NZ/pwRvP26Sox+FWapz3DGCil70H1iGSYu8ENa"
"afUBCGGhT4sk7kl7zS6XiEpMobLq3A==");
ASSERT_FALSE(!(!ec));
alg.verify("testdata", res, ec);
ASSERT_FALSE(!(!ec));
}
TEST(OpenSSLErrorTest, RS256SignErrorCode) {
jwt::algorithm::rs256 alg{rsa_pub_key, rsa_priv_key};
std::vector<multitest_entry> mapping{
{&fail_EVP_MD_CTX_new, 1, jwt::error::signature_generation_error::create_context_failed},
{&fail_EVP_DigestInit, 1, jwt::error::signature_generation_error::signinit_failed},
{&fail_EVP_DigestUpdate, 1, jwt::error::signature_generation_error::signupdate_failed},
{&fail_EVP_SignFinal, 1, jwt::error::signature_generation_error::signfinal_failed}};
run_multitest(mapping, [&alg](std::error_code& ec) {
auto res = alg.sign("testdata", ec);
ASSERT_EQ(res, "");
});
}
TEST(OpenSSLErrorTest, RS256VerifyErrorCode) {
jwt::algorithm::rs256 alg{rsa_pub_key, rsa_priv_key};
auto signature = jwt::base::decode<jwt::alphabet::base64>(
"oCJUeLmIKKVVE/UWhEL/Malx0l9TCoXWNAS2z9o8ZYNaS4POIeadZWeUbLdICx3SCJCnGRwL8JkAmYx1wexT2QGuVXXAtZvRu8ceyuQy"
"AhzGkI9HdADu5YAJsUaLknDUV5hmundXQY8lhwQnKFXW0rl0H8DoFiPQErFmcKI6PA9NVGK/LSiqHqesNeg0wqCTxMmeT6pqI7FH9fDO"
"CaBpwUJ4t5aKoytQ75t13OfUM7tfLlVkFZtI3RndhivxLA5d4Elt/Gv3RhDu6Eiom5NZ/pwRvP26Sox+FWapz3DGCil70H1iGSYu8ENa"
"afUBCGGhT4sk7kl7zS6XiEpMobLq3A==");
std::vector<multitest_entry> mapping{
{&fail_EVP_MD_CTX_new, 1, jwt::error::signature_verification_error::create_context_failed},
{&fail_EVP_DigestInit, 1, jwt::error::signature_verification_error::verifyinit_failed},
{&fail_EVP_DigestUpdate, 1, jwt::error::signature_verification_error::verifyupdate_failed},
{&fail_EVP_VerifyFinal, 1, jwt::error::signature_verification_error::verifyfinal_failed}};
run_multitest(mapping, [&alg, &signature](std::error_code& ec) { alg.verify("testdata", signature, ec); });
}
TEST(OpenSSLErrorTest, LoadECDSAPrivateKeyFromString) {
std::vector<multitest_entry> mapping{
{&fail_BIO_new, 1, jwt::error::ecdsa_error::create_mem_bio_failed},
{&fail_BIO_write, 1, jwt::error::ecdsa_error::load_key_bio_write},
{&fail_PEM_read_bio_PrivateKey, 1, jwt::error::ecdsa_error::load_key_bio_read},
#ifdef JWT_OPENSSL_3_0
{&fail_EVP_PKEY_private_check, 1, jwt::error::ecdsa_error::invalid_key},
{&fail_EVP_PKEY_CTX_new_from_pkey, 1, jwt::error::ecdsa_error::create_context_failed},
#else
{&fail_EC_KEY_check_key, 1, jwt::error::ecdsa_error::invalid_key},
{&fail_EVP_PKEY_get1_EC_KEY, 1, jwt::error::ecdsa_error::invalid_key},
#endif
};
run_multitest(mapping, [](std::error_code& ec) {
try {
jwt::algorithm::es256 alg{"", ecdsa256_priv_key};
FAIL(); // Should never reach this
} catch (const std::system_error& e) { ec = e.code(); }
});
}
TEST(OpenSSLErrorTest, LoadECDSAPublicKeyFromString) {
std::vector<multitest_entry> mapping{
{&fail_BIO_new, 1, jwt::error::ecdsa_error::create_mem_bio_failed},
{&fail_BIO_write, 1, jwt::error::ecdsa_error::load_key_bio_write},
{&fail_PEM_read_bio_PUBKEY, 1, jwt::error::ecdsa_error::load_key_bio_read},
#ifdef JWT_OPENSSL_3_0
{&fail_EVP_PKEY_public_check, 1, jwt::error::ecdsa_error::invalid_key},
{&fail_EVP_PKEY_CTX_new_from_pkey, 1, jwt::error::ecdsa_error::create_context_failed},
#else
{&fail_EC_KEY_check_key, 1, jwt::error::ecdsa_error::invalid_key},
{&fail_EVP_PKEY_get1_EC_KEY, 1, jwt::error::ecdsa_error::invalid_key},
#endif
};
run_multitest(mapping, [](std::error_code& ec) {
try {
jwt::algorithm::es256 alg{ecdsa256_pub_key, ""};
FAIL(); // Should never reach this
} catch (const std::system_error& e) { ec = e.code(); }
});
}
TEST(OpenSSLErrorTest, ECDSACertificate) {
std::vector<multitest_entry> mapping {
{&fail_BIO_new, 1, jwt::error::ecdsa_error::create_mem_bio_failed},
#if !defined(LIBRESSL_VERSION_NUMBER) || LIBRESSL_VERSION_NUMBER < 0x3050300fL
{&fail_BIO_write, 1, jwt::error::ecdsa_error::load_key_bio_write},
#else
{&fail_BIO_write, 1, jwt::error::rsa_error::write_key_failed},
#endif
{&fail_PEM_read_bio_PUBKEY, 1, jwt::error::ecdsa_error::load_key_bio_read},
// extract_pubkey_from_cert
{&fail_BIO_new, 2, jwt::error::rsa_error::create_mem_bio_failed},
{&fail_PEM_read_bio_X509, 1, jwt::error::rsa_error::cert_load_failed},
{&fail_X509_get_pubkey, 1, jwt::error::rsa_error::get_key_failed},
{&fail_PEM_write_bio_PUBKEY, 1, jwt::error::rsa_error::write_key_failed}, {
&fail_BIO_ctrl, 1, jwt::error::rsa_error::convert_to_pem_failed
}
};
run_multitest(mapping, [](std::error_code& ec) {
try {
jwt::algorithm::es256 alg{ecdsa256_certificate};
FAIL(); // Should never reach this
} catch (const std::system_error& e) { ec = e.code(); }
});
}
TEST(OpenSSLErrorTest, ES256Reference) {
jwt::algorithm::es256 alg{ecdsa256_pub_key, ecdsa256_priv_key};
std::error_code ec;
auto res = alg.sign("testdata", ec);
ASSERT_FALSE(!(!ec));
alg.verify("testdata", res, ec);
ASSERT_FALSE(!(!ec));
}
TEST(OpenSSLErrorTest, ES256SignErrorCode) {
jwt::algorithm::es256 alg{ecdsa256_pub_key, ecdsa256_priv_key};
std::vector<multitest_entry> mapping{
{&fail_EVP_MD_CTX_new, 1, jwt::error::signature_generation_error::create_context_failed},
{&fail_EVP_DigestSignInit, 1, jwt::error::signature_generation_error::signinit_failed},
{&fail_EVP_DigestUpdate, 1, jwt::error::signature_generation_error::digestupdate_failed},
{&fail_EVP_DigestSignFinal, 1, jwt::error::signature_generation_error::signfinal_failed},
{&fail_EVP_DigestSignFinal, 2, jwt::error::signature_generation_error::signfinal_failed},
{&fail_d2i_ECDSA_SIG, 1, jwt::error::signature_generation_error::signature_decoding_failed},
};
run_multitest(mapping, [&alg](std::error_code& ec) {
auto res = alg.sign("testdata", ec);
ASSERT_EQ(res, "");
});
}
TEST(OpenSSLErrorTest, ES256VerifyErrorCode) {
jwt::algorithm::es256 alg{ecdsa256_pub_key, ecdsa256_priv_key};
auto signature = jwt::base::decode<jwt::alphabet::base64>(
"aC/NqyHfPw5FDA0yRAnrbkrAlXjsr0obRkCg/HgP+77QYJrAg6YKkKoJwMXjUX8fQrxXKTN7em5L9dtmOep37Q==");
std::vector<multitest_entry> mapping{
{&fail_EVP_MD_CTX_new, 1, jwt::error::signature_verification_error::create_context_failed},
{&fail_EVP_DigestVerifyInit, 1, jwt::error::signature_verification_error::verifyinit_failed},
{&fail_EVP_DigestUpdate, 1, jwt::error::signature_verification_error::verifyupdate_failed},
{&fail_EVP_DigestVerifyFinal, 1, jwt::error::signature_verification_error::invalid_signature},
{&fail_ECDSA_SIG_new, 1, jwt::error::signature_verification_error::create_context_failed},
{&fail_i2d_ECDSA_SIG, 1, jwt::error::signature_verification_error::signature_encoding_failed},
{&fail_i2d_ECDSA_SIG, 2, jwt::error::signature_verification_error::signature_encoding_failed},
};
run_multitest(mapping, [&alg, &signature](std::error_code& ec) { alg.verify("testdata", signature, ec); });
}
TEST(OpenSSLErrorTest, PS256Reference) {
jwt::algorithm::ps256 alg{rsa_pub_key, rsa_priv_key};
std::error_code ec;
auto res = alg.sign("testdata", ec);
ASSERT_FALSE(!(!ec));
alg.verify("testdata", res, ec);
ASSERT_FALSE(!(!ec));
}
TEST(OpenSSLErrorTest, PS256SignErrorCode) {
jwt::algorithm::ps256 alg{rsa_pub_key, rsa_priv_key};
std::vector<multitest_entry> mapping{
{&fail_EVP_MD_CTX_new, 1, jwt::error::signature_generation_error::create_context_failed},
{&fail_EVP_DigestSignInit, 1, jwt::error::signature_generation_error::signinit_failed},
{&fail_EVP_DigestUpdate, 1, jwt::error::signature_generation_error::digestupdate_failed},
{&fail_EVP_DigestSignFinal, 1, jwt::error::signature_generation_error::signfinal_failed},
//TODO: EVP_PKEY_CTX_set_rsa_padding, EVP_PKEY_CTX_set_rsa_pss_saltlen
};
run_multitest(mapping, [&alg](std::error_code& ec) {
auto res = alg.sign("testdata", ec);
ASSERT_EQ(res, "");
});
}
TEST(OpenSSLErrorTest, PS256VerifyErrorCode) {
jwt::algorithm::ps256 alg{rsa_pub_key, rsa_priv_key};
std::string signature =
"LMiWCiW0a/"
"mbU6LK8EZaDQ6TGisqfD+LF46zUbzjhFt02J9yVuf3ZDNTdRgLKKP8nCJUx0SN+5CS2YD268Ioxau5bWs49RVCxtID5DcRpJlSo+Vk+"
"dCmwxhQWHX8HNh3o7kBK5H8fLeTeupuSov+0hH3+"
"GRrYJqZvCdbcadi6amNKCfeIl6a5mp2VCM55NsPoRxsmSzc1G7AHWb1ckOCsm3KY5BL6B074bHgoqO3yaLlKWLAcy4OYyRpJ/wnZQ9PPrhwdq/"
"B59uW3x1QUCKYKgZeqZOoqIP1YgLwvEpPtXYutQCFr4eBKgV7vdtE0wgHR43ka16fi5L4SyaZv53NCg==";
signature = jwt::base::decode<jwt::alphabet::base64>(signature);
std::vector<multitest_entry> mapping{
{&fail_EVP_MD_CTX_new, 1, jwt::error::signature_verification_error::create_context_failed},
{&fail_EVP_DigestVerifyInit, 1, jwt::error::signature_verification_error::verifyinit_failed},
{&fail_EVP_DigestUpdate, 1, jwt::error::signature_verification_error::verifyupdate_failed},
{&fail_EVP_DigestVerifyFinal, 1, jwt::error::signature_verification_error::verifyfinal_failed},
};
run_multitest(mapping, [&alg, &signature](std::error_code& ec) { alg.verify("testdata", signature, ec); });
}
#if !defined(JWT_OPENSSL_1_0_0) && !defined(JWT_OPENSSL_1_1_0)
TEST(OpenSSLErrorTest, EdDSAKey) {
std::vector<multitest_entry> mapping{
// load_private_key_from_string
{&fail_BIO_new, 1, jwt::error::rsa_error::create_mem_bio_failed},
{&fail_BIO_write, 1, jwt::error::rsa_error::load_key_bio_write},
{&fail_PEM_read_bio_PrivateKey, 1, jwt::error::rsa_error::load_key_bio_read},
// load_public_key_from_string
{&fail_BIO_new, 1, jwt::error::rsa_error::create_mem_bio_failed},
{&fail_BIO_write, 1, jwt::error::rsa_error::load_key_bio_write},
// { &fail_PEM_read_bio_PUBKEY, 1, jwt::error::rsa_error::load_key_bio_read }
};
run_multitest(mapping, [](std::error_code& ec) {
try {
jwt::algorithm::ed25519 alg{ed25519_pub_key, ed25519_priv_key};
FAIL(); // Should never reach this
} catch (const std::system_error& e) { ec = e.code(); }
});
}
TEST(OpenSSLErrorTest, EdDSACertificate) {
std::vector<multitest_entry> mapping{// load_public_key_from_string
{&fail_BIO_new, 1, jwt::error::rsa_error::create_mem_bio_failed},
{&fail_BIO_write, 1, jwt::error::rsa_error::load_key_bio_write},
{&fail_PEM_read_bio_PUBKEY, 1, jwt::error::rsa_error::load_key_bio_read},
// extract_pubkey_from_cert
{&fail_BIO_new, 2, jwt::error::rsa_error::create_mem_bio_failed},
{&fail_PEM_read_bio_X509, 1, jwt::error::rsa_error::cert_load_failed},
{&fail_X509_get_pubkey, 1, jwt::error::rsa_error::get_key_failed},
{&fail_PEM_write_bio_PUBKEY, 1, jwt::error::rsa_error::write_key_failed},
{&fail_BIO_ctrl, 1, jwt::error::rsa_error::convert_to_pem_failed}};
run_multitest(mapping, [](std::error_code& ec) {
try {
jwt::algorithm::ed25519 alg{ed25519_certificate};
FAIL(); // Should never reach this
} catch (const std::system_error& e) { ec = e.code(); }
});
}
TEST(OpenSSLErrorTest, Ed25519Reference) {
jwt::algorithm::ed25519 alg{ed25519_pub_key, ed25519_priv_key};
std::error_code ec;
auto res = alg.sign("testdata", ec);
ASSERT_FALSE(!(!ec));
alg.verify("testdata", res, ec);
ASSERT_FALSE(!(!ec));
}
TEST(OpenSSLErrorTest, Ed25519SignErrorCode) {
jwt::algorithm::ed25519 alg{ed25519_pub_key, ed25519_priv_key};
std::vector<multitest_entry> mapping{
{&fail_EVP_MD_CTX_new, 1, jwt::error::signature_generation_error::create_context_failed},
{&fail_EVP_DigestSignInit, 1, jwt::error::signature_generation_error::signinit_failed},
{&fail_EVP_DigestSign, 1, jwt::error::signature_generation_error::signfinal_failed}};
run_multitest(mapping, [&alg](std::error_code& ec) {
auto res = alg.sign("testdata", ec);
ASSERT_EQ(res, "");
});
}
TEST(OpenSSLErrorTest, Ed25519VerifyErrorCode) {
jwt::algorithm::ed25519 alg{ed25519_pub_key, ed25519_priv_key};
auto signature = jwt::base::decode<jwt::alphabet::base64>(
"aC/NqyHfPw5FDA0yRAnrbkrAlXjsr0obRkCg/HgP+77QYJrAg6YKkKoJwMXjUX8fQrxXKTN7em5L9dtmOep37Q==");
std::vector<multitest_entry> mapping{
{&fail_EVP_MD_CTX_new, 1, jwt::error::signature_verification_error::create_context_failed},
{&fail_EVP_DigestVerifyInit, 1, jwt::error::signature_verification_error::verifyinit_failed},
{&fail_EVP_DigestVerify, 1, jwt::error::signature_verification_error::verifyfinal_failed}};
run_multitest(mapping, [&alg, &signature](std::error_code& ec) { alg.verify("testdata", signature, ec); });
}
#endif
#endif
#endif
#endif
@@ -1,6 +0,0 @@
#include <gtest/gtest.h>
int main(int argc, char* argv[]) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
@@ -1,16 +0,0 @@
#include "jwt-cpp/jwt.h"
#include <gtest/gtest.h>
TEST(TokenFormatTest, MissingDot) {
ASSERT_THROW(jwt::decode("eyJhbGciOiJub25lIiwidHlwIjoiSldTIn0.eyJpc3MiOiJhdXRoMCJ9"), std::invalid_argument);
ASSERT_THROW(jwt::decode("eyJhbGciOiJub25lIiwidHlwIjoiSldTIn0eyJpc3MiOiJhdXRoMCJ9."), std::invalid_argument);
ASSERT_THROW(jwt::decode("eyJhbGciOiJub25lIiwidHlwIjoiSldTIn0eyJpc3MiOiJhdXRoMCJ9"), std::invalid_argument);
}
TEST(TokenFormatTest, InvalidChar) {
ASSERT_THROW(jwt::decode("eyJhbGciOiJub25lIiwidHlwIjoiSldTIn0().eyJpc3MiOiJhdXRoMCJ9."), std::runtime_error);
}
TEST(TokenFormatTest, InvalidJSON) {
ASSERT_THROW(jwt::decode("YXsiYWxnIjoibm9uZSIsInR5cCI6IkpXUyJ9YQ.eyJpc3MiOiJhdXRoMCJ9."), std::runtime_error);
}
-801
View File
@@ -1,801 +0,0 @@
#include "jwt-cpp/jwt.h"
#include <gtest/gtest.h>
inline namespace test_keys {
extern std::string rsa_priv_key;
extern std::string rsa_pub_key;
extern std::string rsa_pub_key_invalid;
extern std::string rsa512_priv_key;
extern std::string rsa512_pub_key;
extern std::string rsa512_pub_key_invalid;
extern std::string ecdsa256_certificate;
extern std::string ecdsa256_priv_key;
extern std::string ecdsa256_pub_key;
extern std::string ecdsa256_pub_key_invalid;
extern std::string ecdsa384_priv_key;
extern std::string ecdsa384_pub_key;
extern std::string ecdsa384_pub_key_invalid;
extern std::string ecdsa521_priv_key;
extern std::string ecdsa521_pub_key;
extern std::string ecdsa521_pub_key_invalid;
extern std::string ed25519_priv_key;
extern std::string ed25519_pub_key;
extern std::string ed25519_pub_key_invalid;
extern std::string ed448_priv_key;
extern std::string ed448_pub_key;
extern std::string ed448_pub_key_invalid;
} // namespace test_keys
TEST(TokenTest, DecodeToken) {
std::string token =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCJ9.AbIJTDMFc7yUa5MhvcP03nJPyCPzZtQcGEp-zWfOkEE";
auto decoded = jwt::decode(token);
ASSERT_TRUE(decoded.has_algorithm());
ASSERT_TRUE(decoded.has_type());
ASSERT_FALSE(decoded.has_content_type());
ASSERT_FALSE(decoded.has_key_id());
ASSERT_TRUE(decoded.has_issuer());
ASSERT_FALSE(decoded.has_subject());
ASSERT_FALSE(decoded.has_audience());
ASSERT_FALSE(decoded.has_expires_at());
ASSERT_FALSE(decoded.has_not_before());
ASSERT_FALSE(decoded.has_issued_at());
ASSERT_FALSE(decoded.has_id());
ASSERT_EQ("HS256", decoded.get_algorithm());
ASSERT_EQ("JWS", decoded.get_type());
ASSERT_EQ("auth0", decoded.get_issuer());
}
TEST(TokenTest, CreateToken) {
auto token = jwt::create().set_issuer("auth0").set_type("JWS").sign(jwt::algorithm::none{});
ASSERT_EQ("eyJhbGciOiJub25lIiwidHlwIjoiSldTIn0.eyJpc3MiOiJhdXRoMCJ9.", token);
}
TEST(TokenTest, CreateTokenHS256) {
auto token = jwt::create().set_issuer("auth0").set_type("JWS").sign(jwt::algorithm::hs256{"secret"});
ASSERT_EQ("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCJ9.AbIJTDMFc7yUa5MhvcP03nJPyCPzZtQcGEp-zWfOkEE",
token);
}
TEST(TokenTest, CreateTokenRS256) {
auto token = jwt::create().set_issuer("auth0").set_type("JWS").sign(
jwt::algorithm::rs256(rsa_pub_key, rsa_priv_key, "", ""));
ASSERT_EQ(
"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCJ9.VA2i1ui1cnoD6I3wnji1WAVCf29EekysvevGrT2GXqK1dDMc8"
"HAZCTQxa1Q8NppnpYV-hlqxh-X3Bb0JOePTGzjynpNZoJh2aHZD-GKpZt7OO1Zp8AFWPZ3p8Cahq8536fD8RiBES9jRsvChZvOqA7gMcFc4"
"YD0iZhNIcI7a654u5yPYyTlf5kjR97prCf_OXWRn-bYY74zna4p_bP9oWCL4BkaoRcMxi-IR7kmVcCnvbYqyIrKloXP2qPO442RBGqU7Ov9"
"sGQxiVqtRHKXZR9RbfvjrErY1KGiCp9M5i2bsUHadZEY44FE2jiOmx-uc2z5c05CCXqVSpfCjWbh9gQ",
token);
}
TEST(TokenTest, CreateTokenRS512) {
auto token = jwt::create().set_issuer("auth0").set_type("JWS").sign(
jwt::algorithm::rs512(rsa512_pub_key, rsa512_priv_key, "", ""));
ASSERT_EQ("eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCJ9.GZhnjtsvBl2_KDSxg4JW6xnmNjr2mWhYSZSSQyLKvI0"
"TK86sJKchkt_HDy2IC5l5BGRhq_Xv9pHdA1umidQZG3a7gWvHsujqybCBgBraMTd1wJrCl4QxFg2RYHhHbRqb9BnPJgFD_vryd4GB"
"hfGgejPBCBlGrQtqFGFdHHOjNHY",
token);
}
TEST(TokenTest, CreateTokenPS256) {
auto token = jwt::create().set_issuer("auth0").set_type("JWS").sign(
jwt::algorithm::ps256(rsa_pub_key, rsa_priv_key, "", ""));
// TODO: Find a better way to check if generated signature is valid
// Can't do simple check for equal since pss adds random salt.
}
TEST(TokenTest, CreateTokenPS384) {
auto token = jwt::create().set_issuer("auth0").set_type("JWS").sign(
jwt::algorithm::ps384(rsa_pub_key, rsa_priv_key, "", ""));
// TODO: Find a better way to check if generated signature is valid
// Can't do simple check for equal since pss adds random salt.
}
TEST(TokenTest, CreateTokenPS512) {
auto token = jwt::create().set_issuer("auth0").set_type("JWS").sign(
jwt::algorithm::ps512(rsa_pub_key, rsa_priv_key, "", ""));
// TODO: Find a better way to check if generated signature is valid
// Can't do simple check for equal since pss adds random salt.
}
TEST(TokenTest, CreateTokenES256) {
auto token =
jwt::create().set_issuer("auth0").set_type("JWS").sign(jwt::algorithm::es256("", ecdsa256_priv_key, "", ""));
auto decoded = jwt::decode(token);
ASSERT_THROW(
jwt::verify().allow_algorithm(jwt::algorithm::es256(ecdsa256_pub_key_invalid, "", "", "")).verify(decoded),
jwt::error::signature_verification_exception);
ASSERT_NO_THROW(jwt::verify().allow_algorithm(jwt::algorithm::es256(ecdsa256_pub_key, "", "", "")).verify(decoded));
}
TEST(TokenTest, CreateTokenES256NoPrivate) {
ASSERT_THROW(
[]() {
auto token = jwt::create().set_issuer("auth0").set_type("JWS").sign(
jwt::algorithm::es256(ecdsa256_pub_key, "", "", ""));
}(),
jwt::error::signature_generation_exception);
}
TEST(TokenTest, CreateTokenES384) {
auto token =
jwt::create().set_issuer("auth0").set_type("JWS").sign(jwt::algorithm::es384("", ecdsa384_priv_key, "", ""));
auto decoded = jwt::decode(token);
ASSERT_THROW(
jwt::verify().allow_algorithm(jwt::algorithm::es384(ecdsa384_pub_key_invalid, "", "", "")).verify(decoded),
jwt::error::signature_verification_exception);
ASSERT_NO_THROW(jwt::verify().allow_algorithm(jwt::algorithm::es384(ecdsa384_pub_key, "", "", "")).verify(decoded));
}
TEST(TokenTest, CreateTokenES384NoPrivate) {
ASSERT_THROW(
[]() {
auto token = jwt::create().set_issuer("auth0").set_type("JWS").sign(
jwt::algorithm::es384(ecdsa384_pub_key, "", "", ""));
}(),
jwt::error::signature_generation_exception);
}
TEST(TokenTest, CreateTokenES512) {
auto token =
jwt::create().set_issuer("auth0").set_type("JWS").sign(jwt::algorithm::es512("", ecdsa521_priv_key, "", ""));
auto decoded = jwt::decode(token);
ASSERT_THROW(
jwt::verify().allow_algorithm(jwt::algorithm::es512(ecdsa521_pub_key_invalid, "", "", "")).verify(decoded),
jwt::error::signature_verification_exception);
ASSERT_NO_THROW(jwt::verify().allow_algorithm(jwt::algorithm::es512(ecdsa521_pub_key, "", "", "")).verify(decoded));
}
TEST(TokenTest, CreateTokenES512NoPrivate) {
ASSERT_THROW(
[]() {
auto token = jwt::create().set_issuer("auth0").set_type("JWS").sign(
jwt::algorithm::es512(ecdsa521_pub_key, "", "", ""));
}(),
jwt::error::signature_generation_exception);
}
#if !defined(JWT_OPENSSL_1_0_0) && !defined(JWT_OPENSSL_1_1_0)
TEST(TokenTest, CreateTokenEd25519) {
auto token =
jwt::create().set_issuer("auth0").set_type("JWS").sign(jwt::algorithm::ed25519("", ed25519_priv_key, "", ""));
auto decoded = jwt::decode(token);
ASSERT_THROW(
jwt::verify().allow_algorithm(jwt::algorithm::ed25519(ed25519_pub_key_invalid, "", "", "")).verify(decoded),
jwt::error::signature_verification_exception);
ASSERT_NO_THROW(
jwt::verify().allow_algorithm(jwt::algorithm::ed25519(ed25519_pub_key, "", "", "")).verify(decoded));
}
TEST(TokenTest, CreateTokenEd448) {
auto token =
jwt::create().set_issuer("auth0").set_type("JWS").sign(jwt::algorithm::ed448("", ed448_priv_key, "", ""));
auto decoded = jwt::decode(token);
ASSERT_THROW(
jwt::verify().allow_algorithm(jwt::algorithm::ed448(ed448_pub_key_invalid, "", "", "")).verify(decoded),
jwt::error::signature_verification_exception);
ASSERT_NO_THROW(jwt::verify().allow_algorithm(jwt::algorithm::ed448(ed448_pub_key, "", "", "")).verify(decoded));
}
#endif
TEST(TokenTest, VerifyTokenWrongAlgorithm) {
std::string token =
"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCJ9.VA2i1ui1cnoD6I3wnji1WAVCf29EekysvevGrT2GXqK1dDMc8"
"HAZCTQxa1Q8NppnpYV-hlqxh-X3Bb0JOePTGzjynpNZoJh2aHZD-GKpZt7OO1Zp8AFWPZ3p8Cahq8536fD8RiBES9jRsvChZvOqA7gMcFc4"
"YD0iZhNIcI7a654u5yPYyTlf5kjR97prCf_OXWRn-bYY74zna4p_bP9oWCL4BkaoRcMxi-IR7kmVcCnvbYqyIrKloXP2qPO442RBGqU7Ov9"
"sGQxiVqtRHKXZR9RbfvjrErY1KGiCp9M5i2bsUHadZEY44FE2jiOmx-uc2z5c05CCXqVSpfCjWbh9gQ";
auto verify = jwt::verify().allow_algorithm(jwt::algorithm::none{}).with_issuer("auth0");
auto decoded_token = jwt::decode(token);
ASSERT_THROW(verify.verify(decoded_token), jwt::error::token_verification_exception);
}
TEST(TokenTest, VerifyTokenNoneFail) {
// None algorithm should not have a signature
std::string token = "eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJpYXQiOjE1OTUyNjc1MTZ9.cmFuZG9tc2ln";
auto verify = jwt::verify().allow_algorithm(jwt::algorithm::none{});
auto decoded_token = jwt::decode(token);
ASSERT_THROW(verify.verify(decoded_token), jwt::error::signature_verification_exception);
}
TEST(TokenTest, VerifyTokenRS256FailNoKey) {
ASSERT_THROW(
[]() {
auto verify = jwt::verify().allow_algorithm(jwt::algorithm::rs256("", "", "", "")).with_issuer("auth0");
}(),
jwt::error::rsa_exception);
}
TEST(TokenTest, VerifyTokenRS256) {
std::string token =
"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCJ9.VA2i1ui1cnoD6I3wnji1WAVCf29EekysvevGrT2GXqK1dDMc8"
"HAZCTQxa1Q8NppnpYV-hlqxh-X3Bb0JOePTGzjynpNZoJh2aHZD-GKpZt7OO1Zp8AFWPZ3p8Cahq8536fD8RiBES9jRsvChZvOqA7gMcFc4"
"YD0iZhNIcI7a654u5yPYyTlf5kjR97prCf_OXWRn-bYY74zna4p_bP9oWCL4BkaoRcMxi-IR7kmVcCnvbYqyIrKloXP2qPO442RBGqU7Ov9"
"sGQxiVqtRHKXZR9RbfvjrErY1KGiCp9M5i2bsUHadZEY44FE2jiOmx-uc2z5c05CCXqVSpfCjWbh9gQ";
auto verify =
jwt::verify().allow_algorithm(jwt::algorithm::rs256(rsa_pub_key, rsa_priv_key, "", "")).with_issuer("auth0");
auto decoded_token = jwt::decode(token);
verify.verify(decoded_token);
}
TEST(TokenTest, VerifyTokenRS256PublicOnly) {
std::string token =
"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCJ9.VA2i1ui1cnoD6I3wnji1WAVCf29EekysvevGrT2GXqK1dDMc8"
"HAZCTQxa1Q8NppnpYV-hlqxh-X3Bb0JOePTGzjynpNZoJh2aHZD-GKpZt7OO1Zp8AFWPZ3p8Cahq8536fD8RiBES9jRsvChZvOqA7gMcFc4"
"YD0iZhNIcI7a654u5yPYyTlf5kjR97prCf_OXWRn-bYY74zna4p_bP9oWCL4BkaoRcMxi-IR7kmVcCnvbYqyIrKloXP2qPO442RBGqU7Ov9"
"sGQxiVqtRHKXZR9RbfvjrErY1KGiCp9M5i2bsUHadZEY44FE2jiOmx-uc2z5c05CCXqVSpfCjWbh9gQ";
auto verify = jwt::verify().allow_algorithm(jwt::algorithm::rs256(rsa_pub_key, "", "", "")).with_issuer("auth0");
auto decoded_token = jwt::decode(token);
verify.verify(decoded_token);
}
TEST(TokenTest, VerifyTokenRS256PrivateOnly) {
std::string token =
"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCJ9.VA2i1ui1cnoD6I3wnji1WAVCf29EekysvevGrT2GXqK1dDMc8"
"HAZCTQxa1Q8NppnpYV-hlqxh-X3Bb0JOePTGzjynpNZoJh2aHZD-GKpZt7OO1Zp8AFWPZ3p8Cahq8536fD8RiBES9jRsvChZvOqA7gMcFc4"
"YD0iZhNIcI7a654u5yPYyTlf5kjR97prCf_OXWRn-bYY74zna4p_bP9oWCL4BkaoRcMxi-IR7kmVcCnvbYqyIrKloXP2qPO442RBGqU7Ov9"
"sGQxiVqtRHKXZR9RbfvjrErY1KGiCp9M5i2bsUHadZEY44FE2jiOmx-uc2z5c05CCXqVSpfCjWbh9gQ";
auto verify = jwt::verify().allow_algorithm(jwt::algorithm::rs256("", rsa_priv_key, "", "")).with_issuer("auth0");
auto decoded_token = jwt::decode(token);
verify.verify(decoded_token);
}
TEST(TokenTest, VerifyTokenRS256Fail) {
std::string token =
"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCJ9.VA2i1ui1cnoD6I3wnji1WAVCf29EekysvevGrT2GXqK1dDMc8"
"HAZCTQxa1Q8NppnpYV-hlqxh-X3Bb0JOePTGzjynpNZoJh2aHZD-GKpZt7OO1Zp8AFWPZ3p8Cahq8536fD8RiBES9jRsvChZvOqA7gMcFc4"
"YD0iZhNIcI7a654u5yPYyTlf5kjR97prCf_OXWRn-bYY74zna4p_bP9oWCL4BkaoRcMxi-IR7kmVcCnvbYqyIrKloXP2qPO442RBGqU7Ov9"
"sGQxiVqtRHKXZR9RbfvjrErY1KGiCp9M5i2bsUHadZEY44FE2jiOmx-uc2z5c05CCXqVSpfCjWbh9gQ";
auto verify =
jwt::verify().allow_algorithm(jwt::algorithm::rs256(rsa_pub_key_invalid, "", "", "")).with_issuer("auth0");
auto decoded_token = jwt::decode(token);
ASSERT_THROW(verify.verify(decoded_token), jwt::error::signature_verification_exception);
}
TEST(TokenTest, VerifyTokenRS512) {
std::string token =
"eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCJ9.GZhnjtsvBl2_KDSxg4JW6xnmNjr2mWhYSZ"
"SSQyLKvI0TK86sJKchkt_HDy2IC5l5BGRhq_Xv9pHdA1umidQZG3a7gWvHsujqybCBgBraMTd1wJrCl4QxFg2RYHhHbRqb9BnPJgFD_vryd4"
"GBhfGgejPBCBlGrQtqFGFdHHOjNHY";
auto verify = jwt::verify()
.allow_algorithm(jwt::algorithm::rs512(rsa512_pub_key, rsa512_priv_key, "", ""))
.with_issuer("auth0");
auto decoded_token = jwt::decode(token);
verify.verify(decoded_token);
}
TEST(TokenTest, VerifyTokenRS512PublicOnly) {
std::string token =
"eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCJ9.GZhnjtsvBl2_KDSxg4JW6xnmNjr2mWhYSZ"
"SSQyLKvI0TK86sJKchkt_HDy2IC5l5BGRhq_Xv9pHdA1umidQZG3a7gWvHsujqybCBgBraMTd1wJrCl4QxFg2RYHhHbRqb9BnPJgFD_vryd4"
"GBhfGgejPBCBlGrQtqFGFdHHOjNHY";
auto verify = jwt::verify().allow_algorithm(jwt::algorithm::rs512(rsa512_pub_key, "", "", "")).with_issuer("auth0");
auto decoded_token = jwt::decode(token);
verify.verify(decoded_token);
}
TEST(TokenTest, VerifyTokenRS512PrivateOnly) {
std::string token =
"eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCJ9.GZhnjtsvBl2_KDSxg4JW6xnmNjr2mWhYSZ"
"SSQyLKvI0TK86sJKchkt_HDy2IC5l5BGRhq_Xv9pHdA1umidQZG3a7gWvHsujqybCBgBraMTd1wJrCl4QxFg2RYHhHbRqb9BnPJgFD_vryd4"
"GBhfGgejPBCBlGrQtqFGFdHHOjNHY";
auto verify =
jwt::verify().allow_algorithm(jwt::algorithm::rs512("", rsa512_priv_key, "", "")).with_issuer("auth0");
auto decoded_token = jwt::decode(token);
verify.verify(decoded_token);
}
TEST(TokenTest, VerifyTokenRS512Fail) {
std::string token =
"eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCJ9.GZhnjtsvBl2_KDSxg4JW6xnmNjr2mWhYSZ"
"SSQyLKvI0TK86sJKchkt_HDy2IC5l5BGRhq_Xv9pHdA1umidQZG3a7gWvHsujqybCBgBraMTd1wJrCl4QxFg2RYHhHbRqb9BnPJgFD_vryd4"
"GBhfGgejPBCBlGrQtqFGFdHHOjNHY";
auto verify =
jwt::verify().allow_algorithm(jwt::algorithm::rs512(rsa_pub_key_invalid, "", "", "")).with_issuer("auth0");
auto decoded_token = jwt::decode(token);
ASSERT_THROW(verify.verify(decoded_token), jwt::error::signature_verification_exception);
}
TEST(TokenTest, VerifyTokenHS256) {
std::string token =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCJ9.AbIJTDMFc7yUa5MhvcP03nJPyCPzZtQcGEp-zWfOkEE";
auto verify = jwt::verify().allow_algorithm(jwt::algorithm::hs256{"secret"}).with_issuer("auth0");
auto decoded_token = jwt::decode(token);
verify.verify(decoded_token);
}
TEST(TokenTest, VerifyTokenHS256Fail) {
std::string token =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCJ9.AbIJTDMFc7yUa5MhvcP03nJPyCPzZtQcGEp-zWfOkEE";
auto verify = jwt::verify().allow_algorithm(jwt::algorithm::hs256{"wrongsecret"}).with_issuer("auth0");
auto decoded_token = jwt::decode(token);
ASSERT_THROW(verify.verify(decoded_token), jwt::error::signature_verification_exception);
}
TEST(TokenTest, VerifyTokenHS256FailSignatureLength) {
std::string token =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCJ9.AbIJTDMFc7yUa5MhvcP03nJPyCPzZtQcGEp-zWfOkA";
auto verify = jwt::verify().allow_algorithm(jwt::algorithm::hs256{"secret"}).with_issuer("auth0");
auto decoded_token = jwt::decode(token);
ASSERT_THROW(verify.verify(decoded_token), jwt::error::signature_verification_exception);
}
TEST(TokenTest, VerifyFail) {
{
auto token = jwt::create()
.set_issuer("auth0")
.set_type("JWS")
.set_audience("random")
.set_payload_claim("typetest", picojson::value(10.0))
.sign(jwt::algorithm::none{});
auto decoded_token = jwt::decode(token);
{
auto verify = jwt::verify().allow_algorithm(jwt::algorithm::none{}).with_issuer("auth");
ASSERT_THROW(verify.verify(decoded_token), jwt::error::token_verification_exception);
}
{
auto verify = jwt::verify().allow_algorithm(jwt::algorithm::none{}).with_type("JWT");
ASSERT_THROW(verify.verify(decoded_token), jwt::error::token_verification_exception);
}
{
auto verify = jwt::verify()
.allow_algorithm(jwt::algorithm::none{})
.with_issuer("auth0")
.with_audience(std::set<std::string>{"test"});
ASSERT_THROW(verify.verify(decoded_token), jwt::error::token_verification_exception);
}
{
auto verify =
jwt::verify().allow_algorithm(jwt::algorithm::none{}).with_issuer("auth0").with_audience("test");
ASSERT_THROW(verify.verify(decoded_token), jwt::error::token_verification_exception);
}
{
auto verify =
jwt::verify().allow_algorithm(jwt::algorithm::none{}).with_issuer("auth0").with_subject("test");
ASSERT_THROW(verify.verify(decoded_token), jwt::error::token_verification_exception);
}
{
auto verify = jwt::verify()
.allow_algorithm(jwt::algorithm::none{})
.with_issuer("auth0")
.with_claim("myclaim", jwt::claim(std::string("test")));
ASSERT_THROW(verify.verify(decoded_token), jwt::error::token_verification_exception);
}
{
auto verify = jwt::verify()
.allow_algorithm(jwt::algorithm::none{})
.with_issuer("auth0")
.with_claim("typetest", jwt::claim(picojson::value(true)));
ASSERT_THROW(verify.verify(decoded_token), jwt::error::token_verification_exception);
}
{
jwt::claim object;
std::istringstream iss{R"({ "test": null })"};
iss >> object;
ASSERT_EQ(object.get_type(), jwt::json::type::object);
auto verify = jwt::verify()
.allow_algorithm(jwt::algorithm::none{})
.with_issuer("auth0")
.with_claim("myclaim", object);
ASSERT_THROW(verify.verify(decoded_token), jwt::error::token_verification_exception);
}
}
{
auto token = jwt::create().set_issuer("auth0").set_type("JWS").sign(jwt::algorithm::none{});
auto decoded_token = jwt::decode(token);
{
auto verify =
jwt::verify().allow_algorithm(jwt::algorithm::none{}).with_issuer("auth0").with_audience("test");
ASSERT_THROW(verify.verify(decoded_token), jwt::error::token_verification_exception);
}
}
}
TEST(TokenTest, VerifyTokenES256FailNoKey) {
ASSERT_THROW(
[]() {
auto verify = jwt::verify().allow_algorithm(jwt::algorithm::es256("", "", "", "")).with_issuer("auth0");
}(),
jwt::error::ecdsa_exception);
}
TEST(TokenTest, VerifyTokenES256) {
const std::string token = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9.4iVk3-Y0v4RT4_9IaQlp-8dZ_"
"4fsTzIylgrPTDLrEvTHBTyVS3tgPbr2_IZfLETtiKRqCg0aQ5sh9eIsTTwB1g";
auto verify = jwt::verify().allow_algorithm(jwt::algorithm::es256(ecdsa256_pub_key, "", "", ""));
auto decoded_token = jwt::decode(token);
verify.verify(decoded_token);
}
TEST(TokenTest, VerifyTokenES256Fail) {
const std::string token = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9.4iVk3-Y0v4RT4_9IaQlp-8dZ_"
"4fsTzIylgrPTDLrEvTHBTyVS3tgPbr2_IZfLETtiKRqCg0aQ5sh9eIsTTwB1g";
auto verify = jwt::verify().allow_algorithm(jwt::algorithm::es256(ecdsa256_pub_key_invalid, "", "", ""));
auto decoded_token = jwt::decode(token);
ASSERT_THROW(verify.verify(decoded_token), jwt::error::signature_verification_exception);
}
TEST(TokenTest, VerifyTokenES384) {
const std::string token =
"eyJhbGciOiJFUzM4NCIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCJ9.nTUwWanmj_K1VZM5it1ES-1FbnmRDL-lH3V_Fem-"
"AhMur9Q61yZfKIydrpdavkm_SMxEsUGPVoqkpoEsjFjrtzMDs5s9yaFYD_ydiy1dsn9VbcI55voA3XwEcWFiPHri";
auto verify = jwt::verify().allow_algorithm(jwt::algorithm::es384(ecdsa384_pub_key, "", "", ""));
auto decoded_token = jwt::decode(token);
verify.verify(decoded_token);
}
TEST(TokenTest, VerifyTokenES384Fail) {
const std::string token =
"eyJhbGciOiJFUzM4NCIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCJ9.nTUwWanmj_K1VZM5it1ES-1FbnmRDL-lH3V_Fem-"
"AhMur9Q61yZfKIydrpdavkm_SMxEsUGPVoqkpoEsjFjrtzMDs5s9yaFYD_ydiy1dsn9VbcI55voA3XwEcWFiPHri";
auto verify = jwt::verify().allow_algorithm(jwt::algorithm::es384(ecdsa384_pub_key_invalid, "", "", ""));
auto decoded_token = jwt::decode(token);
ASSERT_THROW(verify.verify(decoded_token), jwt::error::signature_verification_exception);
}
TEST(TokenTest, VerifyTokenES521) {
const std::string token =
"eyJhbGciOiJFUzUxMiIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCJ9.ASF5hh9_Jyujzm3GRBttoth-3I6lCcwqun9Tt7Ekz9_23BN6-"
"BFgwKidECWCNc4VINEqFEFdApC2y3YRdkpKX2etAWI7yYudAlxJ7Z17m6GwAoLOGaeNonsaKOe1UnC5W86eoXrCoPRgzsFTpKIb8NiolcYWjIY"
"-r8gQd7BZ7whaj9Ft";
auto verify = jwt::verify().allow_algorithm(jwt::algorithm::es512(ecdsa521_pub_key, "", "", ""));
auto decoded_token = jwt::decode(token);
verify.verify(decoded_token);
}
TEST(TokenTest, VerifyTokenES521Fail) {
const std::string token =
"eyJhbGciOiJFUzUxMiIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCJ9.ASF5hh9_Jyujzm3GRBttoth-3I6lCcwqun9Tt7Ekz9_23BN6-"
"BFgwKidECWCNc4VINEqFEFdApC2y3YRdkpKX2etAWI7yYudAlxJ7Z17m6GwAoLOGaeNonsaKOe1UnC5W86eoXrCoPRgzsFTpKIb8NiolcYWjIY"
"-r8gQd7BZ7whaj9Ft";
auto verify = jwt::verify().allow_algorithm(jwt::algorithm::es512(ecdsa521_pub_key_invalid, "", "", ""));
auto decoded_token = jwt::decode(token);
ASSERT_THROW(verify.verify(decoded_token), jwt::error::signature_verification_exception);
}
TEST(TokenTest, VerifyTokenPS256) {
std::string token =
"eyJhbGciOiJQUzI1NiIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCJ9.CJ4XjVWdbV6vXGZkD4GdJbtYc80SN9cmPOqRhZBRzOyDRqTFE"
"4MsbdKyQuhAWcvuMOjn-24qOTjVMR_P_uTC1uG6WPLcucxZyLnbb56zbKnEklW2SX0mQnCGewr-93a_vDaFT6Cp45MsF_OwFPRCMaS5CJg-"
"N5KY67UrVSr3s9nkuK9ZTQkyODHfyEUh9F_FhRCATGrb5G7_qHqBYvTvaPUXqzhhpCjN855Tocg7A24Hl0yMwM-XdasucW5xNdKjG_YCkis"
"HX7ax--JiF5GNYCO61eLFteO4THUg-3Z0r4OlGqlppyWo5X5tjcxOZCvBh7WDWfkxA48KFZPRv0nlKA";
auto verify =
jwt::verify().allow_algorithm(jwt::algorithm::ps256(rsa_pub_key, rsa_priv_key, "", "")).with_issuer("auth0");
auto decoded_token = jwt::decode(token);
verify.verify(decoded_token);
}
TEST(TokenTest, VerifyTokenPS256PublicOnly) {
std::string token =
"eyJhbGciOiJQUzI1NiIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCJ9.CJ4XjVWdbV6vXGZkD4GdJbtYc80SN9cmPOqRhZBRzOyDRqTFE"
"4MsbdKyQuhAWcvuMOjn-24qOTjVMR_P_uTC1uG6WPLcucxZyLnbb56zbKnEklW2SX0mQnCGewr-93a_vDaFT6Cp45MsF_OwFPRCMaS5CJg-"
"N5KY67UrVSr3s9nkuK9ZTQkyODHfyEUh9F_FhRCATGrb5G7_qHqBYvTvaPUXqzhhpCjN855Tocg7A24Hl0yMwM-XdasucW5xNdKjG_YCkis"
"HX7ax--JiF5GNYCO61eLFteO4THUg-3Z0r4OlGqlppyWo5X5tjcxOZCvBh7WDWfkxA48KFZPRv0nlKA";
auto verify = jwt::verify().allow_algorithm(jwt::algorithm::ps256(rsa_pub_key, "", "", "")).with_issuer("auth0");
auto decoded_token = jwt::decode(token);
verify.verify(decoded_token);
}
TEST(TokenTest, VerifyTokenPS256Fail) {
std::string token =
"eyJhbGciOiJQUzI1NiIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCJ9.CJ4XjVWdbV6vXGZkD4GdJbtYc80SN9cmPOqRhZBRzOyDRqTFE"
"4MsbdKyQuhAWcvuMOjn-24qOTjVMR_P_uTC1uG6WPLcucxZyLnbb56zbKnEklW2SX0mQnCGewr-93a_vDaFT6Cp45MsF_OwFPRCMaS5CJg-"
"N5KY67UrVSr3s9nkuK9ZTQkyODHfyEUh9F_FhRCATGrb5G7_qHqBYvTvaPUXqzhhpCjN855Tocg7A24Hl0yMwM-XdasucW5xNdKjG_YCkis"
"HX7ax--JiF5GNYCO61eLFteO4THUg-3Z0r4OlGqlppyWo5X5tjcxOZCvBh7WDWfkxA48KFZPRv0nlKA";
auto verify =
jwt::verify().allow_algorithm(jwt::algorithm::ps256(rsa_pub_key_invalid, "", "", "")).with_issuer("auth0");
auto decoded_token = jwt::decode(token);
ASSERT_THROW(verify.verify(decoded_token), jwt::error::signature_verification_exception);
}
TEST(TokenTest, VerifyTokenPS256FailNoKey) {
ASSERT_THROW(
[]() {
auto verify = jwt::verify().allow_algorithm(jwt::algorithm::ps256("", "", "", "")).with_issuer("auth0");
}(),
jwt::error::rsa_exception);
}
#if !defined(JWT_OPENSSL_1_0_0) && !defined(JWT_OPENSSL_1_1_0)
TEST(TokenTest, VerifyTokenEd25519) {
const std::string token =
"eyJhbGciOiJFZERTQSIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCJ9.OujgVcO8xQx5xLcAYWENCRU1SCGH5HcX4MX4o6wU3M4"
"DOnKiNmc0O2AnvQlzr-9cgI4QGQzeC6gz_fgLoesADg";
auto verify = jwt::verify().allow_algorithm(jwt::algorithm::ed25519(ed25519_pub_key, "", "", ""));
auto decoded_token = jwt::decode(token);
verify.verify(decoded_token);
}
TEST(TokenTest, VerifyTokenEd25519Fail) {
const std::string token =
"eyJhbGciOiJFZERTQSIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCJ9.OujgVcO8xQx5xLcAYWENCRU1SCGH5HcX4MX4o6wU3M4"
"DOnKiNmc0O2AnvQlzr-9cgI4QGQzeC6gz_fgLoesADg";
auto verify = jwt::verify().allow_algorithm(jwt::algorithm::ed25519(ed25519_pub_key_invalid, "", "", ""));
auto decoded_token = jwt::decode(token);
ASSERT_THROW(verify.verify(decoded_token), jwt::error::signature_verification_exception);
}
TEST(TokenTest, VerifyTokenEd448) {
const std::string token =
"eyJhbGciOiJFZERTQSIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCJ9.Aldes9jrXZXxfNjuovqmIZ3r2WF4yVXVr2Q8B8SkAmv"
"Bsw_3MHs8HtgKeXbqKFYWpHOCtmZJcH-AWMvoY6FCNdQqbESGTkv58O6tFbXDD_nLejWNAOuvcO2LPMySmkVNQUopmQf_HO62Mug1ngepUDE"
"A";
auto verify = jwt::verify().allow_algorithm(jwt::algorithm::ed448(ed448_pub_key, "", "", ""));
auto decoded_token = jwt::decode(token);
verify.verify(decoded_token);
}
TEST(TokenTest, VerifyTokenEd448Fail) {
const std::string token =
"eyJhbGciOiJFZERTQSIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCJ9.Aldes9jrXZXxfNjuovqmIZ3r2WF4yVXVr2Q8B8SkAmv"
"Bsw_3MHs8HtgKeXbqKFYWpHOCtmZJcH-AWMvoY6FCNdQqbESGTkv58O6tFbXDD_nLejWNAOuvcO2LPMySmkVNQUopmQf_HO62Mug1ngepUDE"
"A";
auto verify = jwt::verify().allow_algorithm(jwt::algorithm::ed448(ed448_pub_key_invalid, "", "", ""));
auto decoded_token = jwt::decode(token);
ASSERT_THROW(verify.verify(decoded_token), jwt::error::signature_verification_exception);
}
#endif
struct test_clock {
jwt::date n;
jwt::date now() const { return n; }
};
TEST(TokenTest, VerifyTokenExpireFail) {
auto token = jwt::create().set_expires_at(std::chrono::system_clock::from_time_t(100)).sign(jwt::algorithm::none{});
auto decoded_token = jwt::decode(token);
auto verify = jwt::verify<test_clock, jwt::traits::kazuho_picojson>({std::chrono::system_clock::from_time_t(110)})
.allow_algorithm(jwt::algorithm::none{});
ASSERT_THROW(verify.verify(decoded_token), jwt::error::token_verification_exception);
std::error_code ec;
ASSERT_NO_THROW(verify.verify(decoded_token, ec));
ASSERT_TRUE(!(!ec));
ASSERT_EQ(ec.category(), jwt::error::token_verification_error_category());
ASSERT_EQ(ec.value(), static_cast<int>(jwt::error::token_verification_error::token_expired));
}
TEST(TokenTest, VerifyTokenExpire) {
auto token = jwt::create().set_expires_at(std::chrono::system_clock::from_time_t(100)).sign(jwt::algorithm::none{});
auto decoded_token = jwt::decode(token);
auto verify = jwt::verify<test_clock, jwt::traits::kazuho_picojson>({std::chrono::system_clock::from_time_t(90)})
.allow_algorithm(jwt::algorithm::none{});
ASSERT_NO_THROW(verify.verify(decoded_token));
std::error_code ec;
ASSERT_NO_THROW(verify.verify(decoded_token, ec));
ASSERT_FALSE(!(!ec));
ASSERT_EQ(ec.value(), 0);
}
TEST(TokenTest, VerifyTokenNBFFail) {
auto token = jwt::create().set_not_before(std::chrono::system_clock::from_time_t(100)).sign(jwt::algorithm::none{});
auto decoded_token = jwt::decode(token);
auto verify = jwt::verify<test_clock, jwt::traits::kazuho_picojson>({std::chrono::system_clock::from_time_t(90)})
.allow_algorithm(jwt::algorithm::none{});
ASSERT_THROW(verify.verify(decoded_token), jwt::error::token_verification_exception);
std::error_code ec;
ASSERT_NO_THROW(verify.verify(decoded_token, ec));
ASSERT_TRUE(!(!ec));
ASSERT_EQ(ec.category(), jwt::error::token_verification_error_category());
ASSERT_EQ(ec.value(), static_cast<int>(jwt::error::token_verification_error::token_expired));
}
TEST(TokenTest, VerifyTokenNBF) {
auto token = jwt::create().set_not_before(std::chrono::system_clock::from_time_t(100)).sign(jwt::algorithm::none{});
auto decoded_token = jwt::decode(token);
auto verify = jwt::verify<test_clock, jwt::traits::kazuho_picojson>({std::chrono::system_clock::from_time_t(110)})
.allow_algorithm(jwt::algorithm::none{});
ASSERT_NO_THROW(verify.verify(decoded_token));
std::error_code ec;
ASSERT_NO_THROW(verify.verify(decoded_token, ec));
ASSERT_FALSE(!(!ec));
ASSERT_EQ(ec.value(), 0);
}
TEST(TokenTest, VerifyTokenIATFail) {
auto token = jwt::create().set_issued_at(std::chrono::system_clock::from_time_t(100)).sign(jwt::algorithm::none{});
auto decoded_token = jwt::decode(token);
auto verify = jwt::verify<test_clock, jwt::traits::kazuho_picojson>({std::chrono::system_clock::from_time_t(90)})
.allow_algorithm(jwt::algorithm::none{});
ASSERT_THROW(verify.verify(decoded_token), jwt::error::token_verification_exception);
std::error_code ec;
ASSERT_NO_THROW(verify.verify(decoded_token, ec));
ASSERT_TRUE(!(!ec));
ASSERT_EQ(ec.category(), jwt::error::token_verification_error_category());
ASSERT_EQ(ec.value(), static_cast<int>(jwt::error::token_verification_error::token_expired));
}
TEST(TokenTest, VerifyTokenIAT) {
auto token = jwt::create().set_issued_at(std::chrono::system_clock::from_time_t(100)).sign(jwt::algorithm::none{});
auto decoded_token = jwt::decode(token);
auto verify = jwt::verify<test_clock, jwt::traits::kazuho_picojson>({std::chrono::system_clock::from_time_t(110)})
.allow_algorithm(jwt::algorithm::none{});
ASSERT_NO_THROW(verify.verify(decoded_token));
std::error_code ec;
ASSERT_NO_THROW(verify.verify(decoded_token, ec));
ASSERT_FALSE(!(!ec));
ASSERT_EQ(ec.value(), 0);
}
TEST(TokenTest, VerifyTokenType) {
auto token = jwt::create().set_type("JWS").sign(jwt::algorithm::none{});
auto decoded_token = jwt::decode(token);
auto verify = jwt::verify().with_type("jws").allow_algorithm(jwt::algorithm::none{});
ASSERT_NO_THROW(verify.verify(decoded_token));
std::error_code ec;
ASSERT_NO_THROW(verify.verify(decoded_token, ec));
ASSERT_FALSE(!(!ec));
ASSERT_EQ(ec.value(), 0);
}
TEST(TokenTest, GetClaimThrows) {
auto token = "eyJhbGciOiJub25lIiwidHlwIjoiSldTIn0.eyJpc3MiOiJhdXRoMCJ9.";
auto decoded_token = jwt::decode(token);
ASSERT_THROW(decoded_token.get_header_claim("test"), jwt::error::claim_not_present_exception);
ASSERT_THROW(decoded_token.get_payload_claim("test"), jwt::error::claim_not_present_exception);
}
TEST(TokenTest, ThrowInvalidKeyLength) {
// We should throw if passed the wrong size
ASSERT_THROW(jwt::algorithm::es256(ecdsa384_pub_key, ""), jwt::error::ecdsa_exception);
ASSERT_THROW(jwt::algorithm::es256("", ecdsa384_priv_key), jwt::error::ecdsa_exception);
ASSERT_THROW(jwt::algorithm::es256(ecdsa384_pub_key, ecdsa384_priv_key), jwt::error::ecdsa_exception);
ASSERT_THROW(jwt::algorithm::es256(ecdsa521_pub_key, ""), jwt::error::ecdsa_exception);
ASSERT_THROW(jwt::algorithm::es256("", ecdsa521_priv_key), jwt::error::ecdsa_exception);
ASSERT_THROW(jwt::algorithm::es256(ecdsa521_pub_key, ecdsa521_priv_key), jwt::error::ecdsa_exception);
// But also if only one cert has the wrong size
ASSERT_THROW(jwt::algorithm::es256(ecdsa256_pub_key, ecdsa384_priv_key), jwt::error::ecdsa_exception);
ASSERT_THROW(jwt::algorithm::es256(ecdsa256_pub_key, ecdsa521_priv_key), jwt::error::ecdsa_exception);
ASSERT_THROW(jwt::algorithm::es384(ecdsa256_pub_key, ""), jwt::error::ecdsa_exception);
ASSERT_THROW(jwt::algorithm::es384("", ecdsa256_priv_key), jwt::error::ecdsa_exception);
ASSERT_THROW(jwt::algorithm::es384(ecdsa256_pub_key, ecdsa256_priv_key), jwt::error::ecdsa_exception);
ASSERT_THROW(jwt::algorithm::es384(ecdsa521_pub_key, ""), jwt::error::ecdsa_exception);
ASSERT_THROW(jwt::algorithm::es384("", ecdsa521_priv_key), jwt::error::ecdsa_exception);
ASSERT_THROW(jwt::algorithm::es384(ecdsa521_pub_key, ecdsa521_priv_key), jwt::error::ecdsa_exception);
ASSERT_THROW(jwt::algorithm::es384(ecdsa384_pub_key, ecdsa256_priv_key), jwt::error::ecdsa_exception);
ASSERT_THROW(jwt::algorithm::es384(ecdsa384_pub_key, ecdsa521_priv_key), jwt::error::ecdsa_exception);
ASSERT_THROW(jwt::algorithm::es512(ecdsa256_pub_key, ""), jwt::error::ecdsa_exception);
ASSERT_THROW(jwt::algorithm::es512("", ecdsa256_priv_key), jwt::error::ecdsa_exception);
ASSERT_THROW(jwt::algorithm::es512(ecdsa256_pub_key, ecdsa256_priv_key), jwt::error::ecdsa_exception);
ASSERT_THROW(jwt::algorithm::es512(ecdsa384_pub_key, ""), jwt::error::ecdsa_exception);
ASSERT_THROW(jwt::algorithm::es512("", ecdsa384_priv_key), jwt::error::ecdsa_exception);
ASSERT_THROW(jwt::algorithm::es512(ecdsa384_pub_key, ecdsa384_priv_key), jwt::error::ecdsa_exception);
ASSERT_THROW(jwt::algorithm::es512(ecdsa521_pub_key, ecdsa256_priv_key), jwt::error::ecdsa_exception);
ASSERT_THROW(jwt::algorithm::es512(ecdsa521_pub_key, ecdsa384_priv_key), jwt::error::ecdsa_exception);
// Make sure we do not throw if the correct params are passed
ASSERT_NO_THROW(jwt::algorithm::es256(ecdsa256_pub_key, ecdsa256_priv_key));
ASSERT_NO_THROW(jwt::algorithm::es384(ecdsa384_pub_key, ecdsa384_priv_key));
ASSERT_NO_THROW(jwt::algorithm::es512(ecdsa521_pub_key, ecdsa521_priv_key));
}
TEST(TokenTest, MoveDecodedToken) {
std::string token0 = "eyJhbGciOiJub25lIiwidHlwIjoiSldTIn0.eyJpc3MiOiJhdXRoMCJ9.";
std::string token1 =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCJ9.AbIJTDMFc7yUa5MhvcP03nJPyCPzZtQcGEp-zWfOkEE";
auto decoded_token0 = jwt::decode(token0);
auto decoded_token1 = jwt::decode(token1);
decoded_token0 = std::move(decoded_token1);
ASSERT_EQ(token1, decoded_token0.get_token());
ASSERT_TRUE(decoded_token0.has_algorithm());
ASSERT_TRUE(decoded_token0.has_type());
ASSERT_FALSE(decoded_token0.has_content_type());
ASSERT_FALSE(decoded_token0.has_key_id());
ASSERT_TRUE(decoded_token0.has_issuer());
ASSERT_FALSE(decoded_token0.has_subject());
ASSERT_FALSE(decoded_token0.has_audience());
ASSERT_FALSE(decoded_token0.has_expires_at());
ASSERT_FALSE(decoded_token0.has_not_before());
ASSERT_FALSE(decoded_token0.has_issued_at());
ASSERT_FALSE(decoded_token0.has_id());
ASSERT_EQ("HS256", decoded_token0.get_algorithm());
ASSERT_EQ("JWS", decoded_token0.get_type());
ASSERT_EQ("auth0", decoded_token0.get_issuer());
}
@@ -1,9 +0,0 @@
cmake_minimum_required(VERSION 3.8)
project(jwt-cpp-installation-tests)
set(TEST CACHE STRING "The test source file to be used")
find_package(jwt-cpp 0.7.0 EXACT REQUIRED CONFIG)
add_executable(test-project ${TEST}.cpp)
target_link_libraries(test-project jwt-cpp::jwt-cpp)
@@ -1,10 +0,0 @@
#ifndef JWT_DISABLE_BASE64
#error "This test expects 'JWT_DISABLE_BASE64' to be defined!"
#endif
#include "jwt-cpp/jwt.h"
int main() {
jwt::date date;
return 0;
}
@@ -1,6 +0,0 @@
#include "jwt-cpp/jwt.h"
int main() {
jwt::claim claim;
return 0;
}

Some files were not shown because too many files have changed in this diff Show More