parent 4e2203f6
# Copyright 2020 UPLEX Nils Goroll Systemoptimierung
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. 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 AUTHOR 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 AUTHOR 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.
#
# Author: Nils Goroll <nils.goroll@uplex.de>
vcl 4.1;
import std;
import re2;
import frozen;
import taskvar;
import blobdigest;
import blob;
sub vcl_init {
# set by caller
new jwt = taskvar.string();
new jwt_re = re2.regex(
"^(([-_0-9a-zA-Z]+)\." +
"([-_0-9a-zA-Z]+))\." +
"([-_0-9a-zA-Z]+)$");
# 1: hdr + payload (for sig check) -> jwt_subj
# 2: hdr
# 3: payload
# 4: sig -> jwt_sig
new jwt_subj = taskvar.string();
new jwt_sig = taskvar.string();
new jwt_exp = taskvar.time();
new jwt_hdr = frozen.parser();
jwt_hdr.expect(".alg", type=STRING, null=false, required=true);
jwt_hdr.expect(".typ", type=STRING, null=false, required=true);
jwt_hdr.expect(".kid", type=STRING, null=false, required=true);
new jwt_payload = frozen.parser();
jwt_payload.expect(".exp", type=NUMBER, null=false, required=true);
jwt_payload.expect(".scope", type=STRING, null=false, required=true);
}
sub recv_jwt_validate {
if (! jwt_re.match(jwt.get())) {
return (synth(400, "jwt dissect error"));
}
if (! jwt_hdr.parse(
blob.transcode(decoding=BASE64URLNOPAD,
encoded=jwt_re.backref(2, "")))) {
return (synth(400, "jwt parse error"));
}
if (jwt_hdr.extract(".typ") != "JWT") {
return (synth(402, "jwt unsupported typ=" + jwt_hdr.extract(".typ")));
}
if (! jwt_payload.parse(
blob.transcode(decoding=BASE64URLNOPAD,
encoded=jwt_re.backref(3, "")))) {
return (synth(402, "jwt payload parse error"));
}
jwt_exp.set(std.time(jwt_payload.extract(".exp", "0", "0")));
if (jwt_exp.get() < now) {
return (synth(400, "jwt expired, .exp=" + jwt_exp.get()));
}
jwt_subj.set(jwt_re.backref(1, ""));
jwt_sig.set(jwt_re.backref(4, ""));
if (jwt_hdr.extract(".alg") == "RS256") {
call recv_jwt_verify_rsa;
} else {
return (synth(402, "jwt unsupported .alg=" + jwt_hdr.extract(".alg")));
}
}
# Copyright 2020 UPLEX Nils Goroll Systemoptimierung
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. 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 AUTHOR 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 AUTHOR 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.
#
# Author: Nils Goroll <nils.goroll@uplex.de>
vcl 4.1;
import crypto;
sub vcl_init {
########################################
# kid test
new jwt_key_test = crypto.key();
jwt_key_test.pem_pubkey({"-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuKnGOHLaY1aoAJJwegD/
w3v3Kk4DDhLmpH92CGJoB2qJo71cTLOFAnt2puAGCP7KYOyqhIuNo37ajb+jEGj7
GpqALW0OrptgNpFj2R/YH6xvQYdS98yjyC8qytTB8XhbsRJcmucn5DgmsCwXL5jQ
hS6AVjS8Lxr6zSE55Qhm5BgwN1AwT9V/byJxAtUiIel7knGwWd7tMHm7O3ZuT5E0
PRXJoJJqHPzcDp8zmdapNypmuzsgsBQoKaQBIv/wEm5UtpcZOFGT7yTVErI8H7A/
KgekUOFA5rJ6TVGWIe4IxiQIYsLQLEXt5vxnSvAospKjiOsjl0UB41mnDOkpXvee
rQIDAQAB
-----END PUBLIC KEY-----
"});
new jwt_verify_test = crypto.verifier(sha256, key=jwt_key_test.use());
}
sub recv_jwt_verify_rsa {
if (jwt_hdr.extract(".kid") == "test") {
jwt_verify_test.reset();
if (jwt_verify_test.update(jwt_subj.get()) &&
jwt_verify_test.valid(blob.decode(BASE64URLNOPAD,
encoded=jwt_sig.get()))) {
return;
}
return (synth(400, "jwt: bad sig kid test"));
}
return (synth(400, "jwt: unknown kid"));
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment