skylothar / lua-resty-jwt Goto Github PK
View Code? Open in Web Editor NEWJWT For The Great Openresty
License: Apache License 2.0
JWT For The Great Openresty
License: Apache License 2.0
Can you add this piece of code to this library. This gets PEM key from JWT token using n and e. It also supports pem Generation using x5c.
Refer:
zmartzone/lua-resty-openidc#71
Code:
https://github.com/pingidentity/lua-resty-openidc/pull/82/files
I'm experiencing memory leak when using X509. Ran through Valgrind and most of the leak points to X509_get_pubkey. Not sure if this a OpenSSL issue or something else.
Specs:
Centos 7 - 64Bit
nginx version: openresty/1.11.2.3
openssl-1.0.1e-60.el7_3.1.x86_64
SkyLothar/lua-resty-jwt 0.1.10
valgrind -v --log-file=memcheck.log --tool=memcheck --leak-check=full openresty-valgrind -c /srv/openresty-apigw/conf/nginx.conf -p /srv/openresty-apigw
==16375== Memcheck, a memory error detector ==16375== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. ==16375== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info ==16375== Command: openresty-valgrind -c /srv/openresty-apigw/conf/nginx.conf -p /srv/openresty-apigw ==16375== Parent PID: 16374 ==16375== --16375-- --16375-- Valgrind options: --16375-- -v --16375-- --log-file=memcheck.log --16375-- --tool=memcheck --16375-- --leak-check=full --16375-- Contents of /proc/version: --16375-- Linux version 3.10.0-514.16.1.el7.x86_64 ([email protected]) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-11) (GCC) ) #1 SMP Wed Apr 12 15:04:24 UTC 2017 --16375-- --16375-- Arch and hwcaps: AMD64, LittleEndian, amd64-cx16-rdtscp-sse3-avx --16375-- Page sizes: currently 4096, max supported 4096 --16375-- Valgrind library directory: /usr/lib64/valgrind --16375-- Reading syms from /usr/local/openresty-valgrind/nginx/sbin/nginx --16375-- object doesn't have a symbol table --16375-- Reading syms from /usr/lib64/ld-2.17.so --16375-- Reading syms from /usr/lib64/valgrind/memcheck-amd64-linux --16375-- object doesn't have a symbol table --16375-- object doesn't have a dynamic symbol table --16375-- Scheduler: using generic scheduler lock implementation. --16375-- Reading suppressions file: /usr/lib64/valgrind/default.supp ==16375== embedded gdbserver: reading from /tmp/vgdb-pipe-from-vgdb-to-16375-by-root-on-vm1 ==16375== embedded gdbserver: writing to /tmp/vgdb-pipe-to-vgdb-from-16375-by-root-on-vm1 ==16375== embedded gdbserver: shared mem /tmp/vgdb-pipe-shared-mem-vgdb-16375-by-root-on-vm1 ==16375== ==16375== TO CONTROL THIS PROCESS USING vgdb (which you probably ==16375== don't want to do, unless you know exactly what you're doing, ==16375== or are doing some strange experiment): ==16375== /usr/lib64/valgrind/../../bin/vgdb --pid=16375 ...command... ==16375== ==16375== TO DEBUG THIS PROCESS USING GDB: start GDB like this ==16375== /path/to/gdb openresty-valgrind ==16375== and then give GDB the following command ==16375== target remote | /usr/lib64/valgrind/../../bin/vgdb --pid=16375 ==16375== --pid is optional if only one valgrind process is running ==16375== --16375-- REDIR: 0x4018e90 (ld-linux-x86-64.so.2:strlen) redirected to 0x38056d91 (???) --16375-- REDIR: 0x4018c60 (ld-linux-x86-64.so.2:index) redirected to 0x38056dab (???) --16375-- Reading syms from /usr/lib64/valgrind/vgpreload_core-amd64-linux.so --16375-- Reading syms from /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so ==16375== WARNING: new redirection conflicts with existing -- ignoring it --16375-- old: 0x04018e90 (strlen ) R-> (0000.0) 0x38056d91 ??? --16375-- new: 0x04018e90 (strlen ) R-> (2007.0) 0x04c2aa90 strlen --16375-- REDIR: 0x4018e10 (ld-linux-x86-64.so.2:strcmp) redirected to 0x4c2bbe0 (strcmp) --16375-- REDIR: 0x4019a00 (ld-linux-x86-64.so.2:mempcpy) redirected to 0x4c2ec20 (mempcpy) --16375-- Reading syms from /usr/lib64/libdl-2.17.so --16375-- Reading syms from /usr/lib64/libpthread-2.17.so --16375-- Reading syms from /usr/lib64/libcrypt-2.17.so --16375-- Reading syms from /usr/local/openresty-valgrind/luajit/lib/libluajit-5.1.so.2.1.0 --16375-- object doesn't have a symbol table --16375-- Reading syms from /usr/lib64/libm-2.17.so --16375-- Reading syms from /usr/local/openresty/pcre/lib/libpcre.so.1.2.8 --16375-- object doesn't have a symbol table --16375-- Reading syms from /usr/local/openresty-debug/openssl/lib/libssl.so.1.0.0 --16375-- object doesn't have a symbol table --16375-- Reading syms from /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0 --16375-- object doesn't have a symbol table --16375-- Reading syms from /usr/local/openresty/zlib/lib/libz.so.1.2.11 --16375-- object doesn't have a symbol table --16375-- Reading syms from /usr/lib64/libGeoIP.so.1.5.0 --16375-- object doesn't have a symbol table --16375-- Reading syms from /usr/lib64/libc-2.17.so --16375-- Reading syms from /usr/lib64/libfreebl3.so --16375-- object doesn't have a symbol table --16375-- Reading syms from /usr/lib64/libgcc_s-4.8.5-20150702.so.1 --16375-- object doesn't have a symbol table --16375-- REDIR: 0x6884ec0 (libc.so.6:strcasecmp) redirected to 0x4a227b0 (_vgnU_ifunc_wrapper) --16375-- REDIR: 0x6881c40 (libc.so.6:strnlen) redirected to 0x4a227b0 (_vgnU_ifunc_wrapper) --16375-- REDIR: 0x6887190 (libc.so.6:strncasecmp) redirected to 0x4a227b0 (_vgnU_ifunc_wrapper) --16375-- REDIR: 0x68846a0 (libc.so.6:memset) redirected to 0x4a227b0 (_vgnU_ifunc_wrapper) --16375-- REDIR: 0x6884650 (libc.so.6:memcpy@GLIBC_2.2.5) redirected to 0x4a227b0 (_vgnU_ifunc_wrapper) --16375-- REDIR: 0x68800c0 (libc.so.6:strcmp) redirected to 0x4a227b0 (_vgnU_ifunc_wrapper) --16375-- REDIR: 0x6881b10 (libc.so.6:strlen) redirected to 0x4a227b0 (_vgnU_ifunc_wrapper) --16375-- REDIR: 0x6889860 (libc.so.6:memcpy@@GLIBC_2.14) redirected to 0x4a227b0 (_vgnU_ifunc_wrapper) --16375-- REDIR: 0x6881b60 (libc.so.6:__GI_strlen) redirected to 0x4c2a9f0 (__GI_strlen) --16375-- REDIR: 0x6883630 (libc.so.6:__GI_strrchr) redirected to 0x4c2a450 (__GI_strrchr) --16375-- REDIR: 0xffffffffff600400 (???:???) redirected to 0x38056d7d (???) --16375-- REDIR: 0x687af70 (libc.so.6:malloc) redirected to 0x4c27b5c (malloc) --16375-- REDIR: 0x68898d0 (libc.so.6:__GI_memcpy) redirected to 0x4c2c580 (__GI_memcpy) --16375-- REDIR: 0x6881d60 (libc.so.6:__GI_strncmp) redirected to 0x4c2b220 (__GI_strncmp) --16375-- REDIR: 0x6884d60 (libc.so.6:__GI_stpcpy) redirected to 0x4c2d8d0 (__GI_stpcpy) --16375-- REDIR: 0x6884870 (libc.so.6:__GI_mempcpy) redirected to 0x4c2e950 (__GI_mempcpy) --16375-- REDIR: 0x695ee60 (libc.so.6:__strlen_sse2_pminub) redirected to 0x4c2a9d0 (strlen) --16375-- REDIR: 0x6944220 (libc.so.6:__memcpy_ssse3_back) redirected to 0x4c2bfa0 (memcpy@@GLIBC_2.14) --16375-- REDIR: 0xffffffffff600000 (???:???) redirected to 0x38056d73 (???) --16375-- REDIR: 0x687b370 (libc.so.6:free) redirected to 0x4c28c56 (free) --16375-- REDIR: 0x689a540 (libc.so.6:__GI_strstr) redirected to 0x4c2eeb0 (__strstr_sse2) --16375-- REDIR: 0x68840c0 (libc.so.6:__GI_memcmp) redirected to 0x4c2d4d0 (__GI_memcmp) --16375-- REDIR: 0x6884700 (libc.so.6:__GI_memset) redirected to 0x4c2de80 (memset) --16375-- REDIR: 0x6884080 (libc.so.6:bcmp) redirected to 0x4a227b0 (_vgnU_ifunc_wrapper) --16375-- REDIR: 0x6959790 (libc.so.6:__memcmp_sse4_1) redirected to 0x4c2d610 (__memcmp_sse4_1) --16375-- REDIR: 0x6883d30 (libc.so.6:memchr) redirected to 0x4c2bc80 (memchr) --16375-- REDIR: 0x692e570 (libc.so.6:__strcmp_sse42) redirected to 0x4c2bb90 (__strcmp_sse42) --16375-- REDIR: 0x687b450 (libc.so.6:realloc) redirected to 0x4c29aae (realloc) --16375-- REDIR: 0x6937f80 (libc.so.6:__strncasecmp_avx) redirected to 0x4c2b450 (strncasecmp) --16375-- REDIR: 0x68835b0 (libc.so.6:strncpy) redirected to 0x4a227b0 (_vgnU_ifunc_wrapper) --16375-- REDIR: 0x688f930 (libc.so.6:__strncpy_sse2_unaligned) redirected to 0x4c2b060 (__strncpy_sse2_unaligned) --16375-- REDIR: 0x68844c0 (libc.so.6:__GI_memmove) redirected to 0x4c2e190 (__GI_memmove) --16375-- REDIR: 0x6880040 (libc.so.6:__GI_strchr) redirected to 0x4c2a580 (__GI_strchr) --16375-- REDIR: 0x688b150 (libc.so.6:strchrnul) redirected to 0x4c2e740 (strchrnul) --16375-- REDIR: 0x6880100 (libc.so.6:__GI_strcmp) redirected to 0x4c2baf0 (__GI_strcmp) --16375-- REDIR: 0x688efa0 (libc.so.6:__GI_strncpy) redirected to 0x4c2adc0 (__GI_strncpy) --16375-- REDIR: 0x687b960 (libc.so.6:calloc) redirected to 0x4c298df (calloc) --16375-- Reading syms from /usr/lib64/libnss_files-2.17.so --16375-- REDIR: 0x6881590 (libc.so.6:__GI_strcpy) redirected to 0x4c2ab90 (__GI_strcpy) --16375-- REDIR: 0x688af10 (libc.so.6:rawmemchr) redirected to 0x4a227b0 (_vgnU_ifunc_wrapper) --16375-- REDIR: 0x688af40 (libc.so.6:__GI___rawmemchr) redirected to 0x4c2e7a0 (__GI___rawmemchr) --16375-- REDIR: 0x6936910 (libc.so.6:__strcasecmp_avx) redirected to 0x4c2b370 (strcasecmp) --16375-- REDIR: 0x6881d20 (libc.so.6:strncmp) redirected to 0x4a227b0 (_vgnU_ifunc_wrapper) --16375-- REDIR: 0x692f320 (libc.so.6:__strncmp_sse42) redirected to 0x4c2b300 (__strncmp_sse42) --16375-- REDIR: 0x68836d0 (libc.so.6:strpbrk) redirected to 0x4a227b0 (_vgnU_ifunc_wrapper) --16375-- REDIR: 0x69366d0 (libc.so.6:__strpbrk_sse42) redirected to 0x4c2efd0 (strpbrk) --16375-- REDIR: 0x6880000 (libc.so.6:index) redirected to 0x4a227b0 (_vgnU_ifunc_wrapper) --16375-- REDIR: 0x692e4c0 (libc.so.6:__strchr_sse42) redirected to 0x4c2a640 (index) --16375-- REDIR: 0x69497c0 (libc.so.6:__memmove_ssse3_back) redirected to 0x4c2bd40 (memcpy@GLIBC_2.2.5) --16375-- REDIR: 0x689ab00 (libc.so.6:strstr) redirected to 0x4a227b0 (_vgnU_ifunc_wrapper) --16375-- REDIR: 0x69304a0 (libc.so.6:__strstr_sse42) redirected to 0x4c2ef40 (__strstr_sse42) ==16375== Syscall param epoll_ctl(event) points to uninitialised byte(s) ==16375== at 0x68F2CBA: epoll_ctl (in /usr/lib64/libc-2.17.so) ==16375== by 0x4605E5: ??? (in /usr/local/openresty-valgrind/nginx/sbin/nginx) ==16375== by 0x460129: ??? (in /usr/local/openresty-valgrind/nginx/sbin/nginx) ==16375== by 0x450A2B: ??? (in /usr/local/openresty-valgrind/nginx/sbin/nginx) ==16375== by 0x45D431: ngx_single_process_cycle (in /usr/local/openresty-valgrind/nginx/sbin/nginx) ==16375== by 0x41CA43: main (in /usr/local/openresty-valgrind/nginx/sbin/nginx) ==16375== Address 0xfff0000a4 is on thread 1's stack ==16375== --16375-- memcheck GC: 1000 nodes, 998 survivors (99.8%) --16375-- memcheck GC: 1414 new table size (stepup) --16375-- memcheck GC: 1414 nodes, 1414 survivors (100.0%) --16375-- memcheck GC: 1999 new table size (stepup) --16375-- memcheck GC: 1999 nodes, 1999 survivors (100.0%) --16375-- memcheck GC: 2827 new table size (stepup) --16375-- REDIR: 0x4019b50 (ld-linux-x86-64.so.2:stpcpy) redirected to 0x4c2dc50 (stpcpy) --16375-- Reading syms from /usr/local/openresty-valgrind/lualib/cjson.so --16375-- object doesn't have a symbol table --16375-- Discarding syms at 0x7fea1e0-0x7fec70c in /usr/local/openresty-valgrind/lualib/cjson.so due to munmap() --16375-- Discarding syms at 0x73d71d0-0x73de3e4 in /usr/lib64/libnss_files-2.17.so due to munmap() ==16375== ==16375== HEAP SUMMARY: ==16375== in use at exit: 24,697,697 bytes in 155,572 blocks ==16375== total heap usage: 9,573,377 allocs, 9,417,805 frees, 937,530,735 bytes allocated ==16375== ==16375== Searching for pointers to 155,572 not-freed blocks ==16375== Checked 11,364,680 bytes ==16375== ==16375== 112 bytes in 2 blocks are possibly lost in loss record 70 of 156 ==16375== at 0x4C27BE3: malloc (vg_replace_malloc.c:299) ==16375== by 0x5FE8044: ??? (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x5FE86FB: CRYPTO_malloc (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x60A3C8B: EVP_PKEY_new (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x60B5F49: X509_PUBKEY_get (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x60D8987: X509_get_pubkey (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x40417D2: ??? ==16375== by 0x7134D97: ??? ==16375== by 0x54941FA: ??? (in /usr/local/openresty-valgrind/luajit/lib/libluajit-5.1.so.2.1.0) ==16375== by 0x54BAAFA: lua_resume (in /usr/local/openresty-valgrind/luajit/lib/libluajit-5.1.so.2.1.0) ==16375== by 0x5623BF: ngx_http_lua_run_thread (in /usr/local/openresty-valgrind/nginx/sbin/nginx) ==16375== by 0x56AA48: ??? (in /usr/local/openresty-valgrind/nginx/sbin/nginx) ==16375== ==16375== 552 bytes in 23 blocks are possibly lost in loss record 96 of 156 ==16375== at 0x4C27BE3: malloc (vg_replace_malloc.c:299) ==16375== by 0x5FE8044: ??? (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x5FE86FB: CRYPTO_malloc (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x602F133: BN_new (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x60B6AE6: ??? (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x60B6C4A: ??? (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x60C1027: asn1_ex_c2i (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x60C0F78: ??? (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x60BF665: ASN1_item_ex_d2i (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x60C0A55: ??? (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x60C062A: ??? (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x60C00CC: ASN1_item_ex_d2i (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== ==16375== 1,664 bytes in 16 blocks are possibly lost in loss record 125 of 156 ==16375== at 0x4C27BE3: malloc (vg_replace_malloc.c:299) ==16375== by 0x5FE8044: ??? (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x5FE86FB: CRYPTO_malloc (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x604C319: BN_MONT_CTX_new (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x604C7D5: BN_MONT_CTX_set_locked (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x606A943: ??? (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x6073E93: RSA_public_decrypt (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x606CE4E: int_rsa_verify (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x606D26B: RSA_verify (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x6072CF4: ??? (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x60AB529: EVP_PKEY_verify (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x60ACC06: EVP_DigestVerifyFinal (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== ==16375== 1,848 bytes in 11 blocks are possibly lost in loss record 127 of 156 ==16375== at 0x4C27BE3: malloc (vg_replace_malloc.c:299) ==16375== by 0x5FE8044: ??? (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x5FE86FB: CRYPTO_malloc (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x606C0BA: RSA_new_method (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x606BFAE: RSA_new (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x606FE81: ??? (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x60BD45B: ??? (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x60BD1A7: ASN1_item_ex_new (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x60BFE6B: ASN1_item_ex_d2i (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x60BF43E: ASN1_item_d2i (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x6070088: d2i_RSAPublicKey (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x60702F0: ??? (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== ==16375== 6,960 bytes in 38 blocks are possibly lost in loss record 141 of 156 ==16375== at 0x4C27BE3: malloc (vg_replace_malloc.c:299) ==16375== by 0x5FE8044: ??? (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x5FE86FB: CRYPTO_malloc (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x602F2FB: ??? (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x602F634: bn_expand2 (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x602FF9B: BN_bin2bn (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x60B6C75: ??? (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x60C1027: asn1_ex_c2i (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x60C0F78: ??? (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x60BF665: ASN1_item_ex_d2i (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x60C0A55: ??? (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x60C062A: ??? (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== ==16375== 7,168 bytes in 28 blocks are possibly lost in loss record 142 of 156 ==16375== at 0x4C27BE3: malloc (vg_replace_malloc.c:299) ==16375== by 0x5FE8044: ??? (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x5FE86FB: CRYPTO_malloc (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x602F2FB: ??? (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x602F634: bn_expand2 (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x602F8A1: BN_copy (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x604C493: BN_MONT_CTX_set (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x604C801: BN_MONT_CTX_set_locked (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x606A943: ??? (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x6073E93: RSA_public_decrypt (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x606CE4E: int_rsa_verify (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x606D26B: RSA_verify (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== ==16375== 22,360 bytes in 43 blocks are possibly lost in loss record 145 of 156 ==16375== at 0x4C27BE3: malloc (vg_replace_malloc.c:299) ==16375== by 0x5FE8044: ??? (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x5FE86FB: CRYPTO_malloc (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x602F2FB: ??? (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x602F634: bn_expand2 (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x60305A7: BN_set_bit (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x604C64E: BN_MONT_CTX_set (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x604C801: BN_MONT_CTX_set_locked (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x606A943: ??? (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x6073E93: RSA_public_decrypt (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x606CE4E: int_rsa_verify (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x606D26B: RSA_verify (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== ==16375== 98,304 bytes in 1 blocks are possibly lost in loss record 146 of 156 ==16375== at 0x4C27BE3: malloc (vg_replace_malloc.c:299) ==16375== by 0x457883: ngx_alloc (in /usr/local/openresty-valgrind/nginx/sbin/nginx) ==16375== by 0x450DC4: ??? (in /usr/local/openresty-valgrind/nginx/sbin/nginx) ==16375== by 0x45D431: ngx_single_process_cycle (in /usr/local/openresty-valgrind/nginx/sbin/nginx) ==16375== by 0x41CA43: main (in /usr/local/openresty-valgrind/nginx/sbin/nginx) ==16375== ==16375== 98,304 bytes in 1 blocks are possibly lost in loss record 147 of 156 ==16375== at 0x4C27BE3: malloc (vg_replace_malloc.c:299) ==16375== by 0x457883: ngx_alloc (in /usr/local/openresty-valgrind/nginx/sbin/nginx) ==16375== by 0x450EA1: ??? (in /usr/local/openresty-valgrind/nginx/sbin/nginx) ==16375== by 0x45D431: ngx_single_process_cycle (in /usr/local/openresty-valgrind/nginx/sbin/nginx) ==16375== by 0x41CA43: main (in /usr/local/openresty-valgrind/nginx/sbin/nginx) ==16375== ==16375== 245,760 bytes in 1 blocks are possibly lost in loss record 148 of 156 ==16375== at 0x4C27BE3: malloc (vg_replace_malloc.c:299) ==16375== by 0x457883: ngx_alloc (in /usr/local/openresty-valgrind/nginx/sbin/nginx) ==16375== by 0x450D54: ??? (in /usr/local/openresty-valgrind/nginx/sbin/nginx) ==16375== by 0x45D431: ngx_single_process_cycle (in /usr/local/openresty-valgrind/nginx/sbin/nginx) ==16375== by 0x41CA43: main (in /usr/local/openresty-valgrind/nginx/sbin/nginx) ==16375== ==16375== 9,466,168 (372,792 direct, 9,093,376 indirect) bytes in 6,657 blocks are definitely lost in loss record 155 of 156 ==16375== at 0x4C27BE3: malloc (vg_replace_malloc.c:299) ==16375== by 0x5FE8044: ??? (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x5FE86FB: CRYPTO_malloc (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x60A3C8B: EVP_PKEY_new (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x60B5F49: X509_PUBKEY_get (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x60D8987: X509_get_pubkey (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x54962EC: ??? (in /usr/local/openresty-valgrind/luajit/lib/libluajit-5.1.so.2.1.0) ==16375== by 0x553428D: ??? (in /usr/local/openresty-valgrind/luajit/lib/libluajit-5.1.so.2.1.0) ==16375== by 0x5559D39: ??? (in /usr/local/openresty-valgrind/luajit/lib/libluajit-5.1.so.2.1.0) ==16375== by 0x54941FA: ??? (in /usr/local/openresty-valgrind/luajit/lib/libluajit-5.1.so.2.1.0) ==16375== by 0x54BAAFA: lua_resume (in /usr/local/openresty-valgrind/luajit/lib/libluajit-5.1.so.2.1.0) ==16375== by 0x5623BF: ngx_http_lua_run_thread (in /usr/local/openresty-valgrind/nginx/sbin/nginx) ==16375== ==16375== 14,644,616 (576,968 direct, 14,067,648 indirect) bytes in 10,303 blocks are definitely lost in loss record 156 of 156 ==16375== at 0x4C27BE3: malloc (vg_replace_malloc.c:299) ==16375== by 0x5FE8044: ??? (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x5FE86FB: CRYPTO_malloc (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x60A3C8B: EVP_PKEY_new (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x60B5F49: X509_PUBKEY_get (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x60D8987: X509_get_pubkey (in /usr/local/openresty-debug/openssl/lib/libcrypto.so.1.0.0) ==16375== by 0x40417D2: ??? ==16375== by 0x7134D97: ??? ==16375== by 0x54941FA: ??? (in /usr/local/openresty-valgrind/luajit/lib/libluajit-5.1.so.2.1.0) ==16375== by 0x54BAAFA: lua_resume (in /usr/local/openresty-valgrind/luajit/lib/libluajit-5.1.so.2.1.0) ==16375== by 0x5623BF: ngx_http_lua_run_thread (in /usr/local/openresty-valgrind/nginx/sbin/nginx) ==16375== by 0x56AA48: ??? (in /usr/local/openresty-valgrind/nginx/sbin/nginx) ==16375== ==16375== LEAK SUMMARY: ==16375== definitely lost: 949,760 bytes in 16,960 blocks ==16375== indirectly lost: 23,161,024 bytes in 135,524 blocks ==16375== possibly lost: 483,032 bytes in 164 blocks ==16375== still reachable: 103,881 bytes in 2,924 blocks ==16375== suppressed: 0 bytes in 0 blocks ==16375== Reachable blocks (those to which a pointer was found) are not shown. ==16375== To see them, rerun with: --leak-check=full --show-leak-kinds=all ==16375== ==16375== Use --track-origins=yes to see where uninitialised values come from ==16375== ERROR SUMMARY: 13 errors from 13 contexts (suppressed: 0 from 0) ==16375== ==16375== 1 errors in context 1 of 13: ==16375== Syscall param epoll_ctl(event) points to uninitialised byte(s) ==16375== at 0x68F2CBA: epoll_ctl (in /usr/lib64/libc-2.17.so) ==16375== by 0x4605E5: ??? (in /usr/local/openresty-valgrind/nginx/sbin/nginx) ==16375== by 0x460129: ??? (in /usr/local/openresty-valgrind/nginx/sbin/nginx) ==16375== by 0x450A2B: ??? (in /usr/local/openresty-valgrind/nginx/sbin/nginx) ==16375== by 0x45D431: ngx_single_process_cycle (in /usr/local/openresty-valgrind/nginx/sbin/nginx) ==16375== by 0x41CA43: main (in /usr/local/openresty-valgrind/nginx/sbin/nginx) ==16375== Address 0xfff0000a4 is on thread 1's stack ==16375== ==16375== ERROR SUMMARY: 13 errors from 13 contexts (suppressed: 0 from 0)
It would be helpful to be able to provide a function or a string as the key to the verify functions. Such a function would be passed the value of kid
from the header as a single parameter, and would return a string to use as the key. This would simplify, for example, using a hash table or a Redis database for looking up keys based off of the kid
parameter.
I actually have some code that does this, and am willing to put together a pull request if it would be something that is desired.
There are 3 PRs open for 6 months plus. We'd really like to use this project in production in our organisation but it difficult to do so comfortably if it's effectively abandoned.
Hi folks, I'm trying to import the lua-resty-jwt in a script but this error module 'resty.aes' not found:
is displayed. I tried to find the lua-resty-aes package on luarocks but I could not.
My goal is to build a script to verify a JWT. My current script:
local jwt = require "resty.jwt"
print("Hello World")
Lua version: 5.3.5
OS: MacOS Sierra
Does anyone have experience generating the token in php?
I encountered two surprises. No direct support for HS256 in php.
But if I have googled correctly, 'sha256' is the sam3 thing.
Results do not match what is generated by /sign ?
I can use curl to get a result --but that seems weird. Maybe it isn't?!
$payload=[
'typ'=>"JWT",
'alg'=>"HS256"
];
$jload = json_encode($payload);
// string hash_hmac ( string $algo , string $data , string $key [, bool $raw_output = false ] )
$key="lua-resty-jwt";
$hash = hash_hmac("sha256", $jload, $key, false);
echo "\nHASHMACF:\n$hash";
$hash = hash_hmac("sha256", $jload,$key, true);
echo "\nHASHMACT:\n$hash";
Appreciate any advice, thank you.
I had assumed I could generate the token in php along with the page.
But worried now I have misunderstood something essential.
I just wanted to bring to you attention. Should resty.string/sha1 be used?
Greetings.
I'm not sure if it's something I'm completely borking up, but I can't see another way to do it.
We use your library to send JWT's from our frontends to our backends out of paranoia - this is working great, php has no trouble decoding these.
I am now trying to use your library to accept a JWT from a different provider (encoded with go-jwt)
This is the public key
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD0UJybPz2/GQAGh/Ri3rvsv60h
fYB3JzoZpWzKBPPXeHC/w7rnOSdOjeqLT4evgfRXjsld9Rx5GYXARiEicTl1l9DU
+P9xk0eptU/Cawz003/XT5tPX+uhmFcC3zIa3oUb/25Kq+IPeq1AUTK9PcJsohFk
pcgtuZvphRLKvFA8uQIDAQAB
-----END PUBLIC KEY-----
This is the token
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0NDQ2OTQxNzksImlhdCI6MTQ0NDY1MDk3OSwiaXAiOiIxNzIuMTYuMjAzLjEiLCJuYmYiOjE0NDQ2NTA5NzksInVzZXIiOiJzaGFubm9uLnd5bnRlciJ9.PLEe64xKFGpkwrX2OameIT6_xSpl5mW_BxFmI4sz20SS_jOaemWrwUBB4gMIUm9LwhxUWTAr5wdLMF30bDJLSfQamf2VeggGMzvjKMQdbJcOPzT6QPmuITAju7bn6WzLzEE5cThIXhOCEdNGKf1xDp9om9T8HVZ15nWpuwwvqwo
This is the output
{"payload":{"nbf":1444650979,"ip":"172.16.203.1","exp":1444694179,"user":"shannon.wynter","iat":1444650979},"reason":"no start line","raw_header":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9","valid":true,"header":{"alg":"RS256","typ":"JWT"},"signature":"PLEe64xKFGpkwrX2OameIT6_xSpl5mW_BxFmI4sz20SS_jOaemWrwUBB4gMIUm9LwhxUWTAr5wdLMF30bDJLSfQamf2VeggGMzvjKMQdbJcOPzT6QPmuITAju7bn6WzLzEE5cThIXhOCEdNGKf1xDp9om9T8HVZ15nWpuwwvqwo","verified":false,"raw_payload":"eyJleHAiOjE0NDQ2OTQxNzksImlhdCI6MTQ0NDY1MDk3OSwiaXAiOiIxNzIuMTYuMjAzLjEiLCJuYmYiOjE0NDQ2NTA5NzksInVzZXIiOiJzaGFubm9uLnd5bnRlciJ9"}```
And this is how I get that
local cookie_value = ngx.var.cookie_lda
if (cookie_value == nil) then
ngx.exit(401)
else
local public_key = [[-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD0UJybPz2/GQAGh/Ri3rvsv60h
fYB3JzoZpWzKBPPXeHC/w7rnOSdOjeqLT4evgfRXjsld9Rx5GYXARiEicTl1l9DU
+P9xk0eptU/Cawz003/XT5tPX+uhmFcC3zIa3oUb/25Kq+IPeq1AUTK9PcJsohFk
pcgtuZvphRLKvFA8uQIDAQAB
-----END PUBLIC KEY-----]]
local jwt_obj = jwt:verify(public_key, cookie_value)
ngx.log(ngx.ERR, cjson.encode(jwt_obj))
end
The debug tool at jwt.io says it's a verified signature but this library won't verify it saying "no start line"
Any help?
What does it mean when the library returns "internal error" for the reason?
I'm testing with a secret of tacos
and following JWT
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6IjJjOGIzNThhLWM3MTctNGQyYi1hMWZmLWY2YzFmMjQxNWFjNCIsImlhdCI6MTQ0MTUxMzMyNCwiZXhwIjoxNDQxNTMxMzI0fQ.vs-xGa4SC6CuzHyb1bWywTyMEffi5MVILnVC3E-zz-g
Testing on jwt.io shows that the token is fine and the secret works. Here's my lua code (running in NGINX)
cjson = require "cjson"
jwt = require "resty.jwt"
local parsed_jwt = jwt:verify("tacos", *insert JWT from above*)
ngx.say(cjson.encode(parsed_jwt))
And the output is
{
"payload":{
"exp":1441531324,
"id":"2c8b358a-c717-4d2b-a1ff-f6c1f2415ac4",
"iat":1441513324
},
"reason":"internal error",
"raw_header":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9",
"valid":true,
"header":{"alg":"HS256","typ":"JWT"},
"signature":"vs-xGa4SC6CuzHyb1bWywTyMEffi5MVILnVC3E-zz-g",
"verified":false,
"raw_payload":"eyJpZCI6IjJjOGIzNThhLWM3MTctNGQyYi1hMWZmLWY2YzFmMjQxNWFjNCIsImlhdCI6MTQ0MTUxMzMyNCwiZXhwIjoxNDQxNTMxMzI0fQ"
}
Any ideas? The payload is parsed correctly.
My env:
After debug i stuck up at hmac.lua at function _M.new(self, key, hash_algo). It seems it returns "nil' to the caller in JWT.lua.
I doubt something going worng with 'require "ffi"' in hmac.lua, though not sure.
Log snippet from nginx error.log:
2018/05/30 13:42:41 [warn] 11009#11009: *1 [lua] jwt.lua:109: my signsecret3, client: 127.0.0.1, server: , request: "POST /pps/v3/core/bookings/createEventBooking HTTP/1.1", host: "localhost:8080"
2018/05/30 13:42:41 [warn] 11009#11009: *1 [lua] hmac.lua:92: new(): inside hmac(in new)secret3, client: 127.0.0.1, server: , request: "POST /pps/v3/core/bookings/createEventBooking HTTP/1.1", host: "localhost:8080"
2018/05/30 13:42:41 [warn] 11009#11009: *1 [lua] nginx-jwt.lua:51: auth(): Invalid token: internal error, client: 127.0.0.1, server: , request: "POST /pps/v3/core/bookings/createEventBooking HTTP/1.1", host: "localhost:8080"
Any help appreciated?
Thanks,
Sanjay
I've been working though auth0/nginx-jwt and following what you've done since with jwt-validators, in my own attempt to add one more bit of functionality. I wanted to propose an addition or see if I missed something in my own implementation.
Motivation: validating a claim containing an array/table of values from which one must match. For example, validating Foo
as a role in a token containing something of the form:
{
"roles" : [
"Foo",
"Bar"
],
iss: "issuer",
.
.
},
I was able to accomplish this combining the validators.any_of
with the nginx-jwt
method for table_contains
, looking something like:
access_by_lua_block {
jwt = require("auth.nginx-jwt")
local valid_roles = {"Foo","Bar"}
.
.
local claim_spec = {
.
roles = validators.any_of(valid_roles, jwt.table_contains, "roles","table","string")
.
}
.
.
}
So, I'm proposing a method that uses table_contains
in a similar form of equality_function
and its friends, altogether allowing to expose a new validator:
validators.contains_any_of(check_values)(opt)
Thoughts?
Hi.
We've been playing with jwt and we've noticed that in your library, you only expire the token if "leeway" is not nil:
if leeway ~= nil and not jwt_obj["reason"] then
Shouldn't the token be expired regardless of "leeway" being present or not, if "exp" is present in the payload of the token?
Thanks for your attention.
I am trying to validate my access_token using https://github.com/pingidentity/lua-resty-openidc#sample-configuration-for-oauth-20-jwt-token-validation. Somehow I wasn't able to succeed. My goal is to protect my apis using this approach. Here is my configuration. Am I missing something here. I am getting 2 issues here. Can someone tell me where I am going wrong. I was able to verify the signature using http://jwt.io
openidc.lua calls https://github.com/pingidentity/lua-resty-openidc/blob/master/lib/resty/openidc.lua#L723
With the below configuration, I am getting openidc_discover(): accessing discovery url (https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration) failed: 20: unable to get local issuer certificate, client:
When I added secret (public key string from my secret.pem file) I am getting "reason":"Verification failed","raw_header":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6InowMzl6ZHNGdWl6cEJmQlZLMVRuMjVRSFlPMCIs
location /api {
access_by_lua '
local opts = {
-- The jwks endpoint must provide a x5c entry
discovery = "https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration"
}
-- call bearer_jwt_verify for OAuth 2.0 JWT validation
local res, err = require("resty.openidc").bearer_jwt_verify(opts)
..
..
}
}
}
I am sending Curl request with authorization token to test if my /api is secured or not like below
curl -i http://myserver.com/api/index.html -H 'Authorization: bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6InowMzl6ZHNGdWl6cEJmQlZLMVRuMjVRSFlPMCIs'
@
I'd like to be able to validate header claims with my claim spec as well -- this could look like:
local claimSpec = {
header = {
alg = validators.equals('HS256'),
kid = validators.equals('MyKeyID'),
custom = validators.equals('other')
},
payload = {
exp = validators.required(validators.opt_is_not_expired()),
}
}
The HMAC library used here isn't the one available via a luarocks install
, which installs the repo maintained here:
https://github.com/jamesmarlowe/lua-resty-hmac
The HMAC library we need instead is this one:
https://github.com/jkeys089/lua-resty-hmac
This was a bummer to me. By default, the following library usage is insecure at not RFC-compliant:
local jwt_obj = jwt:verify(SECRET_KEY, token)
For example, this happily returns jwt_obj.verified
being true, even if the token is expired.
I understand that application developers must always be responsible when using security-relevant libraries. But not validating claims by default and not explicitly warning about this in the docs in practice leads to many vulnerable applications.
claim_spec
by default really is empty, so that validate_claims()
by default just jumps to return true
:
lua-resty-jwt/lib/resty/jwt.lua
Line 685 in 6de9289
The JWT RFC https://tools.ietf.org/html/rfc7519 specifies the behavior of certain claims such as the exp
claim, and I really would have assumed that lua-resty-jwt
(like all of the other JWT libraries I have looked at) would validate those claims by default.
What we IMO need to have, at least: a big big warning in the README that calling local jwt_obj = jwt:verify(SECRET_KEY, token)
alone leads to a validation process that is
What would be better: have an example invocation in the docs that leads to RFC-compliant token verification (i.e. a verification that processes all standard claims in the way as specified in RFC 7519).
What would be best, I think: jwt:verify(key, jwt_token)
should be secure/RFC-compliant. As simple as that. :)
RE https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/
Apologies if this has already been covered. I am not expert enough with LUA to read the code and be sure I have understood.
If I understand the issue, I am not immediately vulnerable, because my usage is internal (I have a secret key, do not use third-parties and public keys). Cf comment from José Romaniello
But still, my preference would be to remove the header all together. Make for a shorter transmission, and remove any clue about which algorithm was used. Cf comment from Federico Rampazzo
I do not yet have the lua mojo to attempt this. Nor do I ask for it.
Thank you for sharing this ! I am excited to be discovering the world of lua+nginx.
Any plan to support for JSON Web Encryption (JWE)?
Are there plans to release version 0.1.3 (which has the validation options in it), or are there other features waiting before a release happens?
Is it planned? or can you explain how to add support for RSA512?
Thanks to all.
I am new to both nginx and lua, so this is probably not an issue.
Just not sure where to turn now.
I am trying to extend the example by adding a user id.
Am I attempting something impossible, or do I need more help with syntax (nginx or lua??)
Many variations tried. The following seems closest...
I get a result for the gentoken location:
curl http://127.0.0.1/gentoken/123
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiIkdXNlciJ9.1fb3i8IsaAXL-syRWQzhiGruOUruCMzUxBxHtig3e8c
But I'm running out of ideas on the "invalid jwt string" response:
curl http://127.0.0.1/verifytoken/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiIkdXNlciJ9.1fb3i8IsaAXL-syRWQzhiGruOUruCMzUxBxHtig3e8c
{"verified":false,"reason":"invalid jwt string"}
location ~ ^/gentoken/(?<user>.+)$ {
add_header X-USER "$user";
content_by_lua '
local cjson = require "cjson"
local jwt = require "resty.jwt"
local jwt_token = jwt:sign(
"lua-resty-jwt",
{
header={typ="JWT", alg="HS256"},
payload={uid="$user"}
}
)
ngx.say(jwt_token)
';
}
location ~ ^/verifytoken/(?<tok>.+)$ {
content_by_lua '
local cjson = require "cjson"
local jwt = require "resty.jwt"
local jwt_obj = jwt:verify("lua-resty-jwt", "$tok")
ngx.say(cjson.encode(jwt_obj))
';
}
Getting segmentation fault
log on signing a new JWT token using RSA private key and certificate
I'm thinking about working on this topic.
Currently we're relying on Cert.new()
and Cert.verify_trust()
that have been initially contributed by @dhiltgen
According to the RFC "The certificate containing the public key corresponding to the key used to digitally sign the JWS MUST be the first certificate.This MAY be followed by additional certificates, with each subsequent certificate being the one used to certify the previous one."
The use case I'm willing to deal with would be as follows
the x5u url would return something like
-----BEGIN CERTIFICATE-----
CERT_1: Leaf cert
-----END CERTIFICATE
-----BEGIN CERTIFICATE-----
CERT_2: Intermediate cert
-----END CERTIFICATE
-----BEGIN CERTIFICATE-----
CERT_3: Self signed root cert
-----END CERTIFICATE
The trusted cert location store would contain the self signed root cert as well (CERT_3).
I've started to study (a bit) the OpenSSL API and think I should be able to send something allowing this. However, that will be my first encounter with OpenSSL and I'd be very grateful for some help.
Would the following sequence of calls do the trick?
Besides, I've got the feeling that the evp.lua Cert API would have to be changed (in order to cope with chains of certs), and I'd prefer to potentially have some feedback regarding how it should shaped (once again, no real experience dealing with chain of certs, so I'm not sure I'd properly think of all the potential use cases and corner cases).
On the other hand, would anyone be already cooking some code in order to make this happen, I'd be happy to beta test it 😉
Thoughts?
I am able to validate the token at jwt.io. Signature validation is also true using my public key.
2018/01/15 06:13:11 [debug] 256#256: *78 [lua] openidc.lua:737: openidc_load_jwt_and_verify_crypto(): jwt: {"signature":"Jb9T5QlRDIJMdhcC_jQ9bZlCKuRBEWe9BJd70g0sw1UJbznKwXb46eGsaGgAF1aorsZaEQqefAxkL5rfgp9dPVETyAQrToGD74QloStLq_15oeCLa0wAeJvHGb4x_pEGNqAjLYHu04MaguQfVZsVulM80kxBLCQ7ILJvii06HuU","reason":"too long",
"reason":"too long" - what could be the reason it repeatedly shows "too long" and verification fails on nginx ?
Reference - zmartzone/lua-resty-openidc#135
How to set expire time when create a new jwt token?
And how to check a token is expired? Does below codes working?
local jwt_obj = jwt:verify("jwt-key", token,
{
lifetime_grace_period = 120,
require_exp_claim = true
}
)
on the RHEL5 find the problem:
[error] 21301#0: *1101 lua entry thread aborted: runtime error: /home/###/###/openresty/lualib/resty/jwt.lua:494: attempt to index a nil value;
but it is ok on my mac;
Any schedule for getting another release (0.1.5?) with the recent changes?
I met a verify error which reason is "interval error", then I modify this line to jwt_obj[str_const.reason] = cjson.decode(ret)
, then I got a reason "everything is awesome~ :p", is there some logic missed in your code?
Hello,
First of all, let me say that my knowledge of Lua can be measured in "days", so please be gentle :-)
I have been using the library for the last weeks, and I it seems that there is a critical bug in the validation of tokens when using asymmetric algorithms (RS256 or RS512).
In the following code in jwt.lua _M:verify_jwt_object
:
...
if alg == str_const.RS256 then
local verified, err = verifier:verify(message, sig, evp.CONST.SHA256_DIGEST)
elseif alg == str_const.RS512 then
local verified, err = verifier:verify(message, sig, evp.CONST.SHA512_DIGEST)
end
if not verified then
jwt_obj[str_const.reason] = err
end
else
jwt_obj[str_const.reason] = "Unsupported algorithm " .. alg
end
if not jwt_obj[str_const.reason] then
jwt_obj[str_const.verified] = true
jwt_obj[str_const.reason] = str_const.everything_awesome
end
return jwt_obj
...
As far as I understand, this piece of code creates variables verified
and err
in local block scope, meaning that out of the if-then-else they will be nil
, no matter what happens after the verification. Then the next piece of code will set the result verified
to true depending on reason
, which was assigned to nil from the err
value.
The end result seems to be that, no matter which key is passed, when this code path is reached the verification will always succeed.
I did a quick fix on my code with something like the following and it seems to work (please excuse my poor Lua):
-- a previous check makes sure that 'alg' can only be either 'str_const.RS256'
-- or 'str_const.RS512'
local evp_digest = nil
if alg == str_const.RS256 then
evp_digest = evp.CONST.SHA256_DIGEST
else
evp_digest = evp.CONST.SHA512_DIGEST
end
local verified, err = verifier:verify(message, sig, evp_digest)
if not verified then
jwt_obj[str_const.reason] = err
end
else
jwt_obj[str_const.reason] = "Unsupported algorithm " .. alg
end
if not jwt_obj[str_const.reason] then
jwt_obj[str_const.verified] = true
jwt_obj[str_const.reason] = str_const.everything_awesome
end
return jwt_obj
Am I missing anything here?
Sample CI output excerpt from https://travis-ci.org/SkyLothar/lua-resty-jwt#L224 :
lua-resty-jwt-tests exited with code 1
The command "docker-compose up" exited with 0.
Done. Your build exited with 0.
Hi,
I have the following JWT token (generated from keycloak ):
eyJhbGciOiJSUzI1NiJ9.eyJqdGkiOiI5ZTVlYTkxYS05ZDk0LTQ2M2YtYjVlMi00Y2U0YWRjMzM2MzYiLCJleHAiOjE0NTgyOTQ0NzcsIm5iZiI6MCwiaWF0IjoxNDU4Mjk0MTc3LCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMvVGVzdCIsImF1ZCI6IlRlc3RDbGllbnQiLCJzdWIiOiIzYzFmMjBkOS1kNDgxLTQzN2QtOWZlOC03YzU0YzZhNDY1ZTYiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJUZXN0Q2xpZW50Iiwic2Vzc2lvbl9zdGF0ZSI6IjlkZTJlNDYyLThmMGUtNGU3Yi05MmM2LTEzMzc5MDQ4OGM2NiIsImNsaWVudF9zZXNzaW9uIjoiNTI3MDkyODMtYzNmNy00ZGQxLWExMjYtOGRmNjBmNDRhNWU5IiwiYWxsb3dlZC1vcmlnaW5zIjpbXSwicmVzb3VyY2VfYWNjZXNzIjp7ImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJ2aWV3LXByb2ZpbGUiXX19LCJuYW1lIjoiIiwicHJlZmVycmVkX3VzZXJuYW1lIjoidGVzdCJ9.fujEnidGKs1F2RRG-MGKP-aQDa8DqzR3nQDpt-TQDQ1rBbj4xdI2UDFL1tgMNj-V--xf_bKujf0ROM5VUd-AOdR0n5dnmO8pgm02P-0Pc5Ycat2ADJoL3TlJJSE2SkZNPQ-MS3DN2d_bnJak3If3OwlzXH7puOVgxGnjNnWWTm_nZXi2Y1gdUOdMOzbUDR--e2-hDPwZG5PS4xUX_XbMMVhPAwYqsEfpPdYVXgcoF7czjWPFPqtaEXy0BvJashdsy-Tv56wusKrt38tWP5MA6qWxtXNP4Cho-RGdAI6jDgmsJKE-jDSME7vVy-5i6w1NI_hr_4zakOLzySfcsFgYRg
Public key:
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArNMMislfx2MqXNLP5rFOZ5/K54qpI2JitGBoosOuxBGnNS8nbsqDW7VoXEDooR3KrZoJQurxKuvFQ/RnEWpNNd6wZnussIbmQzYKOBhzpu3ksOena7enfxAVTfc5WiuU1+NwP9AEbJJWSPskMkEINluk+aCL5y8d27q3Rooo9bvtcrR4f7RxvHnv1mzaXGP2b7W7AO2qMoiizmZWWKTxeea2RmGniNFHbI2i0SVTQWdW3KKo+iX98SC0HCw8KnFI6wbwABDnel7xLz+LRinw9+Jr9gQdAPFZIY1tKyKiqzGkCnz3N3DPdE3dHON8Mnsh1Lwv9FQurYdwB0vvfH5ZhQIDAQAB
Unfortunately when verifying the token with lua.jwt:
local jwt_obj = jwt:verify(cert, jwt_token)
The token is not verified and the reason is "Wrong tag" which I wasn't able to decipher what it means.
{"payload":{"nbf":0,"azp":"TestClient","client_session":"52709283-c3f7-4dd1-a126-8df60f44a5e9","iat":1458294177,"iss":"http://localhost:8080/auth/realms/Test","aud":"TestClient","preferred_username":"test","name":"","session_state":"9de2e462-8f0e-4e7b-92c6-133790488c66","sub":"3c1f20d9-d481-437d-9fe8-7c54c6a465e6","exp":1458294477,"resource_access":{"account":{"roles":["manage-account","view-profile"]}},"jti":"9e5ea91a-9d94-463f-b5e2-4ce4adc33636","allowed-origins":{},"typ":"Bearer"},"reason":"wrong tag","raw_header":"eyJhbGciOiJSUzI1NiJ9","valid":true,"header":{"alg":"RS256"},"signature":"fujEnidGKs1F2RRG-MGKP-aQDa8DqzR3nQDpt-TQDQ1rBbj4xdI2UDFL1tgMNj-V--xf_bKujf0ROM5VUd-AOdR0n5dnmO8pgm02P-0Pc5Ycat2ADJoL3TlJJSE2SkZNPQ-MS3DN2d_bnJak3If3OwlzXH7puOVgxGnjNnWWTm_nZXi2Y1gdUOdMOzbUDR--e2-hDPwZG5PS4xUX_XbMMVhPAwYqsEfpPdYVXgcoF7czjWPFPqtaEXy0BvJashdsy-Tv56wusKrt38tWP5MA6qWxtXNP4Cho-RGdAI6jDgmsJKE-jDSME7vVy-5i6w1NI_hr_4zakOLzySfcsFgYRg","verified":false,"raw_payload":"eyJqdGkiOiI5ZTVlYTkxYS05ZDk0LTQ2M2YtYjVlMi00Y2U0YWRjMzM2MzYiLCJleHAiOjE0NTgyOTQ0NzcsIm5iZiI6MCwiaWF0IjoxNDU4Mjk0MTc3LCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMvVGVzdCIsImF1ZCI6IlRlc3RDbGllbnQiLCJzdWIiOiIzYzFmMjBkOS1kNDgxLTQzN2QtOWZlOC03YzU0YzZhNDY1ZTYiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJUZXN0Q2xpZW50Iiwic2Vzc2lvbl9zdGF0ZSI6IjlkZTJlNDYyLThmMGUtNGU3Yi05MmM2LTEzMzc5MDQ4OGM2NiIsImNsaWVudF9zZXNzaW9uIjoiNTI3MDkyODMtYzNmNy00ZGQxLWExMjYtOGRmNjBmNDRhNWU5IiwiYWxsb3dlZC1vcmlnaW5zIjpbXSwicmVzb3VyY2VfYWNjZXNzIjp7ImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJ2aWV3LXByb2ZpbGUiXX19LCJuYW1lIjoiIiwicHJlZmVycmVkX3VzZXJuYW1lIjoidGVzdCJ9"}
The same token and public key pass verification in java libraries.
Luarocks installation fails.
In my ubuntu desktop machine:
$sudo luarocks install lua-resty-jwt
Warning: falling back to curl - install luasec to get native HTTPS support
Installing https://luarocks.org/lua-resty-jwt-0.1.10-0.src.rock
Error: Couldn't extract archive .: unrecognized filename extension
And in my Dockerfile (based on CentOS):
Step 6/11 : RUN luarocks install lua-resty-jwt
---> Running in dd206fdf553c
Warning: falling back to curl - install luasec to get native HTTPS support
Error: Unrecognized filename extension .
Installing https://luarocks.org/lua-resty-jwt-0.1.10-0.src.rock...
Using https://luarocks.org/lua-resty-jwt-0.1.10-0.src.rock... switching to 'build' mode
The command '/bin/sh -c luarocks install lua-resty-jwt' returned a non-zero code: 1
The lib provides a way to validates certs through jwt:set_trusted_certs_file("/path/to/may/cert.pem")
.
We're currently assessing the integrity of jwts by
x5u
claim against a trusted root one (set through jwt:set_trusted_certs_file("/path/to/may/cert.pem")
)However, it is unclear for me how we should cope with a renewal of the trusted root cert. Should the old one and the new one be concatenated in the .pem
file?
Would you be against a stricter kind of jwt validation?
Currently when the exp
|nbf
claim are not expressed as a number, they're silently ignored.
Two options:
jwt:enforce_strict_validation(bool)
for instance)In accordance with https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/
Most, if not all JWT libraries require specifying the verification algorithm when verifying.
I'd like to bundle my project with fixed implementation of jwe. Any ideas when will be a next release? Is there anything that blocks the next release?
from rfc
5.2.2.1. AES_CBC_HMAC_SHA2 Encryption
The number of octets in the input key K MUST be the sum of
MAC_KEY_LEN and ENC_KEY_LEN. The values of these parameters are
specified by the Authenticated Encryption algorithms in Sections
5.2.3 through 5.2.5.
5.2.3. AES_128_CBC_HMAC_SHA_256
The input key K is 32 octets long.
ENC_KEY_LEN is 16 octets.
MAC_KEY_LEN is 16 octets.
5.2.5. AES_256_CBC_HMAC_SHA_512 AES_256_CBC_HMAC_SHA_512 is based on AES_128_CBC_HMAC_SHA_256, but
with the following differences: The input key K is 64 octets long instead of 32.
ENC_KEY_LEN is 32 octets instead of 16.
MAC_KEY_LEN is 32 octets instead of 16.
but in code:
local function derive_keys(enc, secret_key)
local key_size_bytes = 16
if enc == str_const.A128CBC_HS256 then
key_size_bytes = 16
elseif enc == str_const.A256CBC_HS512 then
key_size_bytes = 32
end
if not secret_key then
secret_key = resty_random.bytes(key_size_bytes,true)
end
if #secret_key ~= key_size_bytes then
error({reason="The pre-shared content key must be ".. key_size_bytes})
end
local derived_key_size = key_size_bytes / 2
mac_key = string_sub(secret_key, 1, derived_key_size)
enc_key =string_sub(secret_key, derived_key_size)
return secret_key, mac_key, enc_key
end
Related to #36.
openssl ecparam -name secp521r1 -genkey -out ES512.pem && openssl ec -in ES512.pem -pubout >> ES512.pem
lua-resty-jwt/lib/resty/jwt.lua
Lines 601 to 606 in ee1d024
In the code above, the comment talks about not handling the case of both x5c and x5u are defined
. However, it is possible to get that far down in the code path if both x5c
and x5u
are nil
. Is that supposed to be a different case that should be handled?
According to RFC 7515, both x5c
and x5u
as header parameters are optional it seems...?
Hi - I was wondering what do you think about tagging the releases? It would make easier/more explicit to request a specific version when deploying/building lua-resty-jwt.
It would give you a release page within Github to easily refer to/download versions.
Been playing around with guard examples and noticed the following:
Getting this exception:
2017/09/12 13:26:07 [error] 7#7: *5 lua entry thread aborted: runtime error: /usr/local/openresty/site/lualib/resty/jwt.lua:696: bad argument #1 to 'pairs' (table expected, got number)
stack traceback:
coroutine 0:
[C]: in function 'pairs'
/usr/local/openresty/site/lualib/resty/jwt.lua:696: in function 'validate_claims'
/usr/local/openresty/site/lualib/resty/jwt.lua:728: in function 'verify'
/usr/local/openresty/nginx/conf/lua/jwtguard.lua:13: in function </usr/local/openresty/nginx/conf/lua/jwtguard.lua:1>, client: ..., server: localhost, request: "GET /test/ HTTP/1.1", host: "..."
My token does not have any claim and seems like 3rd argument on below line causing this issue:
here
If 3rd argument removed, everything seems to work as expected.
Thanks for a great library!
That's not up to date:
lua-resty-jwt/lib/resty/jwt.lua
Line 7 in 6de9289
I am fairly new to Lua and coming from Ruby it is hard to live without package managers. Any chance you can add the rockspec and publish to luarocks?
Eg.
package = 'lua-resty-jwt'
version = '0.1.2-0'
source = {
url = "git://github.com/SkyLothar/lua-resty-jwt",
branch = "master"
}
description = {
summary = 'JWT for ngx_lua and LuaJIT.',
detailed = [[
This library requires an nginx build
with OpenSSL, the ngx_lua module,
the LuaJIT 2.0, the lua-resty-hmac,
and the lua-resty-string,
]],
homepage = 'https://github.com/SkyLothar/lua-resty-jwt',
license = 'Apache License Version 2'
}
dependencies = {
'lua >= 5.1',
'lua-resty-hmac >= 1.0',
'lua-resty-string >= 0.09',
}
build = {
type = 'builtin',
modules = {
['resty.jwt'] = 'lib/resty/jwt',
['resty.evp'] = 'lib/resty/evp'
}
}
Hi,
debian will ship nginx with openssl 1.1 support, meaning... one won't be able to
run this module in next's debian stable. Any plans about that ?
I don't know if it's possible (for licensing/other reasons), but it would be nice to include the stuff inside of "vendor/resty" in the packaged distribution when builds are made.
Again - not a super urgent issue - and it's something that can be grabbed separately, but it's kind of nice to have a distribution package that contains all the required files.
Hello,
Currently, I'm using your library for an another project, I would like to import it from OPM.
Could you push your library on it please ?
I also created a ticket on lua-resty-hmac to ask them to push their project on OPM.
Thank you.
I'm trying to verify a token that uses this jwk:
{
kid = "20171030-00:00:00",
alg = "RS256",
n = "AIueZ4JvoqY1imSaLGLLjCAEe3n/1CdHlnjtRjSLAsK69/ucL3slei3ParNHhuCmhE16LoHwnBXRbjy+GTPjmfLH4HMqbsMrEjGF5FYLW/6JjHJFyUzkWkYh+W/I99FBRC+J2oXSgD0t4iblV4BMYVJljjigMzzTrQT0h2OtXonX2B2vTjwO+nC9oNVI2fY09eDtsyaJOynaduej8Mgo6w8if/q23R0+fQuPxVkY/tr3o6eeUARcVye74mqyPBtNH+Ear894w4ipgSyvl2NAFrGF79CPWypnN8OFPqMMvATXEDeh1VBSnEUqum8bvvjI6S2w32OFxoDQ9zXW5wTMQsU=",
x5c = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAi55ngm+ipjWKZJosYsuMIAR7ef/UJ0eWeO1GNIsCwrr3+5wveyV6Lc9qs0eG4KaETXougfCcFdFuPL4ZM+OZ8sfgcypuwysSMYXkVgtb/omMckXJTORaRiH5b8j30UFEL4nahdKAPS3iJuVXgExhUmWOOKAzPNOtBPSHY61eidfYHa9OPA76cL2g1UjZ9jT14O2zJok7Kdp256PwyCjrDyJ/+rbdHT59C4/FWRj+2vejp55QBFxXJ7viarI8G00f4Rqvz3jDiKmBLK+XY0AWsYXv0I9bKmc3w4U+owy8BNcQN6HVUFKcRSq6bxu++MjpLbDfY4XGgND3NdbnBMxCxQIDAQAB",
kty = "RSA",
e = "AQAB"
}
I couldn't find a good way to convert that to a pem in lua so I'm using a node script with the jwk-to-pem library. That gives me a key like this:
-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEAi55ngm+ipjWKZJosYsuMIAR7ef/UJ0eWeO1GNIsCwrr3+5wveyV6
Lc9qs0eG4KaETXougfCcFdFuPL4ZM+OZ8sfgcypuwysSMYXkVgtb/omMckXJTORa
RiH5b8j30UFEL4nahdKAPS3iJuVXgExhUmWOOKAzPNOtBPSHY61eidfYHa9OPA76
cL2g1UjZ9jT14O2zJok7Kdp256PwyCjrDyJ/+rbdHT59C4/FWRj+2vejp55QBFxX
J7viarI8G00f4Rqvz3jDiKmBLK+XY0AWsYXv0I9bKmc3w4U+owy8BNcQN6HVUFKc
RSq6bxu++MjpLbDfY4XGgND3NdbnBMxCxQIDAQAB
-----END RSA PUBLIC KEY-----
I see this issue #7 that ends with a merged PR about supporting RSA public keys, but I'm still getting the "no start line" error when I call jwt:verify_jwt_obj
.
nginx version: openresty/1.13.6.1
lua-resty-jwt
0.2.0-0 (installed) - /usr/local/openresty/luajit/lib/luarocks/rocks
The way that the "auth" function of the code at https://github.com/auth0/nginx-jwt is pretty nice. It seems to me that this would be a nicer (and more flexible) alternative to the verification code that is currently being worked on.
Basically, you specify a table with claims you want to verify. Existence of a claim key requires the presence of it. The value of the claims can either be a string (in which case, it's matched against the string value in the payload), or a function which takes a single parameter (the value from the payload) and returns true or false.
It seems that the current validation of nbf and exp (and the grace period and issuers check) could be done using this mechanism instead, if it were available.
I actually have some code that does this, and am willing to put together a pull request if it would be something that is desired.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.