update for cross compile
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
build
|
||||
bin
|
||||
.vscode
|
||||
.idea
|
||||
cmake-build-debug
|
||||
+2
-3
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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 = {}
|
||||
|
||||
@@ -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
|
||||
@@ -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
@@ -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
|
||||
@@ -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
|
||||
-18
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
@@ -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
@@ -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 }}
|
||||
@@ -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 .
|
||||
@@ -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 }}
|
||||
@@ -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
|
||||
@@ -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
@@ -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.
|
||||
@@ -1,155 +0,0 @@
|
||||
<img src="https://raw.githubusercontent.com/Thalhammer/jwt-cpp/master/.github/logo.svg" alt="logo" width="100%">
|
||||
|
||||
[](https://github.com/Thalhammer/jwt-cpp/blob/master/LICENSE)
|
||||
[](https://app.codacy.com/gh/Thalhammer/jwt-cpp/dashboard)
|
||||
[![Linux Badge][Linux]][Cross-Platform]
|
||||
[![MacOS Badge][MacOS]][Cross-Platform]
|
||||
[![Windows Badge][Windows]][Cross-Platform]
|
||||
[](https://coveralls.io/github/Thalhammer/jwt-cpp?branch=master)
|
||||
|
||||
[](https://thalhammer.github.io/jwt-cpp/)
|
||||
|
||||
[](https://github.com/Thalhammer/jwt-cpp/stargazers)
|
||||
[](https://github.com/Thalhammer/jwt-cpp/releases)
|
||||
[](https://repology.org/project/jwt-cpp/versions)
|
||||
[](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
|
||||
[](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()
|
||||
@@ -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
|
||||
@@ -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 */});
|
||||
```
|
||||
@@ -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.
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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()
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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");
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
Reference in New Issue
Block a user