├── .gitattributes ├── .gitignore ├── .travis.yml ├── Makefile ├── README.markdown ├── dist.ini ├── lib └── resty │ ├── aes.lua │ ├── md5.lua │ ├── random.lua │ ├── sha.lua │ ├── sha1.lua │ ├── sha224.lua │ ├── sha256.lua │ ├── sha384.lua │ ├── sha512.lua │ └── string.lua ├── t ├── aes.t ├── aes_allocation.t ├── atoi.t ├── md5.t ├── random.t ├── sha1.t ├── sha224.t ├── sha256.t ├── sha384.t ├── sha512.t └── version.t └── valgrind.suppress /.gitattributes: -------------------------------------------------------------------------------- 1 | *.t linguist-language=Text 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | *.swo 3 | *~ 4 | go 5 | t/servroot/ 6 | reindex 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | dist: focal 3 | 4 | branches: 5 | only: 6 | - "master" 7 | 8 | os: linux 9 | 10 | language: c 11 | 12 | compiler: 13 | - gcc 14 | 15 | cache: 16 | directories: 17 | - download-cache 18 | 19 | env: 20 | global: 21 | - JOBS=3 22 | - NGX_BUILD_JOBS=$JOBS 23 | - LUAJIT_PREFIX=/opt/luajit21 24 | - LUAJIT_LIB=$LUAJIT_PREFIX/lib 25 | - LUAJIT_INC=$LUAJIT_PREFIX/include/luajit-2.1 26 | - LUA_INCLUDE_DIR=$LUAJIT_INC 27 | - LUA_CMODULE_DIR=/lib 28 | - OPENSSL_PREFIX=/opt/ssl 29 | - OPENSSL_LIB=$OPENSSL_PREFIX/lib 30 | - OPENSSL_INC=$OPENSSL_PREFIX/include 31 | - LD_LIBRARY_PATH=$LUAJIT_LIB:$LD_LIBRARY_PATH 32 | - TEST_NGINX_SLEEP=0.006 33 | matrix: 34 | - NGINX_VERSION=1.27.1 OPENSSL_VER=1.1.1w 35 | 36 | install: 37 | - if [ ! -d download-cache ]; then mkdir download-cache; fi 38 | - if [ ! -f download-cache/openssl-$OPENSSL_VER.tar.gz ]; then wget -O download-cache/openssl-$OPENSSL_VER.tar.gz https://www.openssl.org/source/openssl-$OPENSSL_VER.tar.gz; fi 39 | - sudo apt-get install -qq -y axel 40 | - cpanm --sudo --notest Test::Nginx > build.log 2>&1 || (cat build.log && exit 1) 41 | - wget http://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz 42 | - git clone https://github.com/openresty/openresty.git ../openresty 43 | - git clone https://github.com/openresty/nginx-devel-utils.git 44 | - git clone https://github.com/simpl/ngx_devel_kit.git ../ndk-nginx-module 45 | - git clone https://github.com/openresty/lua-nginx-module.git ../lua-nginx-module 46 | - git clone https://github.com/openresty/lua-resty-core.git ../lua-resty-core 47 | - git clone https://github.com/openresty/lua-resty-lrucache.git ../lua-resty-lrucache 48 | - git clone https://github.com/openresty/no-pool-nginx.git ../no-pool-nginx 49 | - git clone -b v2.1-agentzh https://github.com/openresty/luajit2.git 50 | - git clone https://github.com/openresty/mockeagain.git 51 | 52 | script: 53 | - cd luajit2/ 54 | - make -j$JOBS CCDEBUG=-g Q= PREFIX=$LUAJIT_PREFIX CC=$CC XCFLAGS='-DLUA_USE_APICHECK -DLUA_USE_ASSERT' > build.log 2>&1 || (cat build.log && exit 1) 55 | - sudo make install PREFIX=$LUAJIT_PREFIX > build.log 2>&1 || (cat build.log && exit 1) 56 | - cd .. 57 | - tar zxf download-cache/openssl-$OPENSSL_VER.tar.gz 58 | - cd openssl-$OPENSSL_VER/ 59 | - ./config shared --prefix=$OPENSSL_PREFIX -DPURIFY > build.log 2>&1 || (cat build.log && exit 1) 60 | - make -j$JOBS > build.log 2>&1 || (cat build.log && exit 1) 61 | - sudo make PATH=$PATH install_sw > build.log 2>&1 || (cat build.log && exit 1) 62 | - cd ../mockeagain/ && make CC=$CC -j$JOBS && cd .. 63 | - export PATH=$PWD/work/nginx/sbin:$PWD/nginx-devel-utils:$PATH 64 | - export LD_PRELOAD=$PWD/mockeagain/mockeagain.so 65 | - export LD_LIBRARY_PATH=$PWD/mockeagain:$LD_LIBRARY_PATH 66 | - export TEST_NGINX_RESOLVER=8.8.4.4 67 | - export NGX_BUILD_CC=$CC 68 | - ngx-build $NGINX_VERSION --with-ipv6 --with-http_realip_module --with-http_ssl_module --with-cc-opt="-I$OPENSSL_INC" --with-ld-opt="-L$OPENSSL_LIB -Wl,-rpath,$OPENSSL_LIB" --add-module=../ndk-nginx-module --add-module=../lua-nginx-module --with-debug > build.log 2>&1 || (cat build.log && exit 1) 69 | - nginx -V 70 | - ldd `which nginx`|grep -E 'luajit|ssl|pcre' 71 | - prove -r t 72 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | OPENRESTY_PREFIX=/usr/local/openresty 2 | 3 | PREFIX ?= /usr/local 4 | LUA_INCLUDE_DIR ?= $(PREFIX)/include 5 | LUA_LIB_DIR ?= $(PREFIX)/lib/lua/$(LUA_VERSION) 6 | INSTALL ?= install 7 | 8 | .PHONY: all test install 9 | 10 | all: ; 11 | 12 | install: all 13 | $(INSTALL) -d $(DESTDIR)/$(LUA_LIB_DIR)/resty 14 | $(INSTALL) lib/resty/*.lua $(DESTDIR)/$(LUA_LIB_DIR)/resty 15 | 16 | test: all 17 | PATH=$(OPENRESTY_PREFIX)/nginx/sbin:$$PATH prove -I../test-nginx/lib -r t 18 | 19 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | Name 2 | ==== 3 | 4 | lua-resty-string - String utilities and common hash functions for ngx_lua and LuaJIT 5 | 6 | Table of Contents 7 | ================= 8 | 9 | * [Name](#name) 10 | * [Status](#status) 11 | * [Description](#description) 12 | * [Synopsis](#synopsis) 13 | * [Author](#author) 14 | * [Copyright and License](#copyright-and-license) 15 | * [See Also](#see-also) 16 | 17 | Status 18 | ====== 19 | 20 | This library is considered experimental and still under active development. 21 | 22 | The API is still in flux and may change without notice. 23 | 24 | Description 25 | =========== 26 | 27 | This library requires an nginx build with OpenSSL, 28 | the [ngx_lua module](http://wiki.nginx.org/HttpLuaModule), and [LuaJIT 2.0](http://luajit.org/luajit.html). 29 | 30 | Synopsis 31 | ======== 32 | 33 | ```lua 34 | # nginx.conf: 35 | 36 | lua_package_path "/path/to/lua-resty-string/lib/?.lua;;"; 37 | 38 | server { 39 | location = /test { 40 | content_by_lua_file conf/test.lua; 41 | } 42 | } 43 | 44 | -- conf/test.lua: 45 | 46 | local resty_sha1 = require "resty.sha1" 47 | 48 | local sha1 = resty_sha1:new() 49 | if not sha1 then 50 | ngx.say("failed to create the sha1 object") 51 | return 52 | end 53 | 54 | local ok = sha1:update("hello, ") 55 | if not ok then 56 | ngx.say("failed to add data") 57 | return 58 | end 59 | 60 | ok = sha1:update("world") 61 | if not ok then 62 | ngx.say("failed to add data") 63 | return 64 | end 65 | 66 | local digest = sha1:final() -- binary digest 67 | 68 | local str = require "resty.string" 69 | ngx.say("sha1: ", str.to_hex(digest)) 70 | -- output: "sha1: b7e23ec29af22b0b4e41da31e868d57226121c84" 71 | 72 | local resty_md5 = require "resty.md5" 73 | local md5 = resty_md5:new() 74 | if not md5 then 75 | ngx.say("failed to create md5 object") 76 | return 77 | end 78 | 79 | local ok = md5:update("hel") 80 | if not ok then 81 | ngx.say("failed to add data") 82 | return 83 | end 84 | 85 | -- md5:update() with an optional "len" parameter 86 | ok = md5:update("loxxx", 2) 87 | if not ok then 88 | ngx.say("failed to add data") 89 | return 90 | end 91 | 92 | local digest = md5:final() 93 | 94 | local str = require "resty.string" 95 | ngx.say("md5: ", str.to_hex(digest)) 96 | -- yield "md5: 5d41402abc4b2a76b9719d911017c592" 97 | 98 | local resty_sha224 = require "resty.sha224" 99 | local str = require "resty.string" 100 | local sha224 = resty_sha224:new() 101 | ngx.say(sha224:update("hello")) 102 | local digest = sha224:final() 103 | ngx.say("sha224: ", str.to_hex(digest)) 104 | 105 | local resty_sha256 = require "resty.sha256" 106 | local str = require "resty.string" 107 | local sha256 = resty_sha256:new() 108 | ngx.say(sha256:update("hello")) 109 | local digest = sha256:final() 110 | ngx.say("sha256: ", str.to_hex(digest)) 111 | 112 | local resty_sha512 = require "resty.sha512" 113 | local str = require "resty.string" 114 | local sha512 = resty_sha512:new() 115 | ngx.say(sha512:update("hello")) 116 | local digest = sha512:final() 117 | ngx.say("sha512: ", str.to_hex(digest)) 118 | 119 | local resty_sha384 = require "resty.sha384" 120 | local str = require "resty.string" 121 | local sha384 = resty_sha384:new() 122 | ngx.say(sha384:update("hel")) 123 | ngx.say(sha384:update("lo")) 124 | local digest = sha384:final() 125 | ngx.say("sha384: ", str.to_hex(digest)) 126 | 127 | local resty_random = require "resty.random" 128 | local str = require "resty.string" 129 | local random = resty_random.bytes(16) 130 | -- generate 16 bytes of pseudo-random data 131 | ngx.say("pseudo-random: ", str.to_hex(random)) 132 | 133 | local resty_random = require "resty.random" 134 | local str = require "resty.string" 135 | local strong_random = resty_random.bytes(16,true) 136 | -- attempt to generate 16 bytes of 137 | -- cryptographically strong random data 138 | while strong_random == nil do 139 | strong_random = resty_random.bytes(16,true) 140 | end 141 | ngx.say("random: ", str.to_hex(strong_random)) 142 | 143 | local aes = require "resty.aes" 144 | local str = require "resty.string" 145 | local aes_128_cbc_md5 = aes:new("AKeyForAES") 146 | -- the default cipher is AES 128 CBC with 1 round of MD5 147 | -- for the key and a nil salt 148 | local encrypted = aes_128_cbc_md5:encrypt("Secret message!") 149 | ngx.say("AES 128 CBC (MD5) Encrypted HEX: ", str.to_hex(encrypted)) 150 | ngx.say("AES 128 CBC (MD5) Decrypted: ", aes_128_cbc_md5:decrypt(encrypted)) 151 | 152 | local aes = require "resty.aes" 153 | local str = require "resty.string" 154 | local aes_256_cbc_sha512x5 = aes:new("AKeyForAES-256-CBC", 155 | "MySalt!!", aes.cipher(256,"cbc"), aes.hash.sha512, 5) 156 | -- AES 256 CBC with 5 rounds of SHA-512 for the key 157 | -- and a salt of "MySalt!!" 158 | -- Note: salt can be either nil or exactly 8 characters long 159 | local encrypted = aes_256_cbc_sha512x5:encrypt("Really secret message!") 160 | ngx.say("AES 256 CBC (SHA-512, salted) Encrypted HEX: ", str.to_hex(encrypted)) 161 | ngx.say("AES 256 CBC (SHA-512, salted) Decrypted: ", 162 | aes_256_cbc_sha512x5:decrypt(encrypted)) 163 | 164 | local aes = require "resty.aes" 165 | local str = require "resty.string" 166 | local aes_128_cbc_with_iv = assert(aes:new("1234567890123456", 167 | nil, aes.cipher(128,"cbc"), {iv="1234567890123456"})) 168 | -- AES 128 CBC with IV and no SALT 169 | local encrypted = aes_128_cbc_with_iv:encrypt("Really secret message!") 170 | ngx.say("AES 128 CBC (WITH IV) Encrypted HEX: ", str.to_hex(encrypted)) 171 | ngx.say("AES 128 CBC (WITH IV) Decrypted: ", 172 | aes_128_cbc_with_iv:decrypt(encrypted)) 173 | 174 | local aes = require "resty.aes" 175 | local str = require "resty.string" 176 | local enable_padding = false 177 | local aes_256_cbc_with_padding = aes:new( 178 | key, nil, aes.cipher(256,"cbc"), {iv = string.sub(key, 1, 16)}, nil, 179 | nil, enable_padding) 180 | -- AES-256 CBC (custom keygen, user padding with block_size=32) 181 | local text = "hello" 182 | local block_size = 32 183 | local pad = block_size - #text % 32 184 | local text_paded = text .. string.rep(string.char(pad), pad) 185 | local encrypted = aes_256_cbc_with_padding:encrypt(text_paded) 186 | ngx.say("AES-256 CBC (custom keygen, user padding with block_size=32) HEX: ", 187 | str.to_hex(encrypted)) 188 | ``` 189 | 190 | [Back to TOC](#table-of-contents) 191 | 192 | Author 193 | ====== 194 | 195 | Yichun "agentzh" Zhang (章亦春) 196 | 197 | [Back to TOC](#table-of-contents) 198 | 199 | Copyright and License 200 | ===================== 201 | 202 | This module is licensed under the BSD license. 203 | 204 | Copyright (C) 2012-2018, by Yichun "agentzh" Zhang (章亦春) , OpenResty Inc. 205 | 206 | All rights reserved. 207 | 208 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 209 | 210 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 211 | 212 | * 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. 213 | 214 | 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. 215 | 216 | [Back to TOC](#table-of-contents) 217 | 218 | See Also 219 | ======== 220 | * the ngx_lua module: http://wiki.nginx.org/HttpLuaModule 221 | 222 | [Back to TOC](#table-of-contents) 223 | 224 | -------------------------------------------------------------------------------- /dist.ini: -------------------------------------------------------------------------------- 1 | name=lua-resty-string 2 | abstract=String utilities and common hash functions for ngx_lua and LuaJIT 3 | author=Yichun "agentzh" Zhang (agentzh) 4 | is_original=yes 5 | license=2bsd 6 | lib_dir=lib 7 | doc_dir=lib 8 | repo_link=https://github.com/openresty/lua-resty-string 9 | main_module=lib/resty/string.lua 10 | requires=luajit >= 2.1.0 11 | -------------------------------------------------------------------------------- /lib/resty/aes.lua: -------------------------------------------------------------------------------- 1 | -- Copyright (C) by Yichun Zhang (agentzh) 2 | 3 | 4 | --local asn1 = require "resty.asn1" 5 | local ffi = require "ffi" 6 | local ffi_new = ffi.new 7 | local ffi_gc = ffi.gc 8 | local ffi_str = ffi.string 9 | local ffi_copy = ffi.copy 10 | local C = ffi.C 11 | local setmetatable = setmetatable 12 | --local error = error 13 | local type = type 14 | 15 | 16 | local _M = { _VERSION = '0.16' } 17 | 18 | local mt = { __index = _M } 19 | 20 | local EVP_CTRL_AEAD_SET_IVLEN = 0x09 21 | local EVP_CTRL_AEAD_GET_TAG = 0x10 22 | local EVP_CTRL_AEAD_SET_TAG = 0x11 23 | 24 | ffi.cdef[[ 25 | typedef struct engine_st ENGINE; 26 | 27 | typedef struct evp_cipher_st EVP_CIPHER; 28 | typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX; 29 | 30 | typedef struct env_md_ctx_st EVP_MD_CTX; 31 | typedef struct env_md_st EVP_MD; 32 | 33 | const EVP_MD *EVP_md5(void); 34 | const EVP_MD *EVP_sha(void); 35 | const EVP_MD *EVP_sha1(void); 36 | const EVP_MD *EVP_sha224(void); 37 | const EVP_MD *EVP_sha256(void); 38 | const EVP_MD *EVP_sha384(void); 39 | const EVP_MD *EVP_sha512(void); 40 | 41 | const EVP_CIPHER *EVP_aes_128_ecb(void); 42 | const EVP_CIPHER *EVP_aes_128_cbc(void); 43 | const EVP_CIPHER *EVP_aes_128_cfb1(void); 44 | const EVP_CIPHER *EVP_aes_128_cfb8(void); 45 | const EVP_CIPHER *EVP_aes_128_cfb128(void); 46 | const EVP_CIPHER *EVP_aes_128_ofb(void); 47 | const EVP_CIPHER *EVP_aes_128_ctr(void); 48 | const EVP_CIPHER *EVP_aes_192_ecb(void); 49 | const EVP_CIPHER *EVP_aes_192_cbc(void); 50 | const EVP_CIPHER *EVP_aes_192_cfb1(void); 51 | const EVP_CIPHER *EVP_aes_192_cfb8(void); 52 | const EVP_CIPHER *EVP_aes_192_cfb128(void); 53 | const EVP_CIPHER *EVP_aes_192_ofb(void); 54 | const EVP_CIPHER *EVP_aes_192_ctr(void); 55 | const EVP_CIPHER *EVP_aes_256_ecb(void); 56 | const EVP_CIPHER *EVP_aes_256_cbc(void); 57 | const EVP_CIPHER *EVP_aes_256_cfb1(void); 58 | const EVP_CIPHER *EVP_aes_256_cfb8(void); 59 | const EVP_CIPHER *EVP_aes_256_cfb128(void); 60 | const EVP_CIPHER *EVP_aes_256_ofb(void); 61 | const EVP_CIPHER *EVP_aes_128_gcm(void); 62 | const EVP_CIPHER *EVP_aes_192_gcm(void); 63 | const EVP_CIPHER *EVP_aes_256_gcm(void); 64 | 65 | EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(); 66 | void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *a); 67 | int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx); 68 | 69 | int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int padding); 70 | 71 | int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, 72 | ENGINE *impl, unsigned char *key, const unsigned char *iv); 73 | 74 | int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, 75 | const unsigned char *in, int inl); 76 | 77 | int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); 78 | 79 | int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, 80 | ENGINE *impl, unsigned char *key, const unsigned char *iv); 81 | 82 | int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, 83 | const unsigned char *in, int inl); 84 | 85 | int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl); 86 | 87 | int EVP_BytesToKey(const EVP_CIPHER *type,const EVP_MD *md, 88 | const unsigned char *salt, const unsigned char *data, int datal, 89 | int count, unsigned char *key,unsigned char *iv); 90 | 91 | int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr); 92 | ]] 93 | 94 | local hash 95 | hash = { 96 | md5 = C.EVP_md5(), 97 | sha1 = C.EVP_sha1(), 98 | sha224 = C.EVP_sha224(), 99 | sha256 = C.EVP_sha256(), 100 | sha384 = C.EVP_sha384(), 101 | sha512 = C.EVP_sha512() 102 | } 103 | _M.hash = hash 104 | 105 | local EVP_MAX_BLOCK_LENGTH = 32 106 | 107 | local cipher 108 | cipher = function (size, _cipher) 109 | local _size = size or 128 110 | local _cipher = _cipher or "cbc" 111 | local func = "EVP_aes_" .. _size .. "_" .. _cipher 112 | if C[func] then 113 | return { size=_size, cipher=_cipher, method=C[func]()} 114 | else 115 | return nil 116 | end 117 | end 118 | _M.cipher = cipher 119 | 120 | function _M.new(self, key, salt, _cipher, _hash, hash_rounds, iv_len, enable_padding) 121 | local encrypt_ctx = C.EVP_CIPHER_CTX_new() 122 | if encrypt_ctx == nil then 123 | return nil, "no memory" 124 | end 125 | 126 | ffi_gc(encrypt_ctx, C.EVP_CIPHER_CTX_free) 127 | 128 | local decrypt_ctx = C.EVP_CIPHER_CTX_new() 129 | if decrypt_ctx == nil then 130 | return nil, "no memory" 131 | end 132 | 133 | ffi_gc(decrypt_ctx, C.EVP_CIPHER_CTX_free) 134 | 135 | local _cipher = _cipher or cipher() 136 | local _hash = _hash or hash.md5 137 | local hash_rounds = hash_rounds or 1 138 | local _cipherLength = _cipher.size/8 139 | local gen_key = ffi_new("unsigned char[?]",_cipherLength) 140 | local gen_iv = ffi_new("unsigned char[?]",_cipherLength) 141 | iv_len = iv_len or _cipherLength 142 | -- enable padding by default 143 | local padding = (enable_padding == nil or enable_padding) and 1 or 0 144 | 145 | if type(_hash) == "table" then 146 | if not _hash.iv then 147 | return nil, "iv is needed" 148 | end 149 | 150 | --[[ Depending on the encryption algorithm, the length of iv will be 151 | different. For detailed, please refer to 152 | https://www.openssl.org/docs/man1.1.0/man3/EVP_CIPHER_CTX_ctrl.html 153 | ]] 154 | iv_len = #_hash.iv 155 | if iv_len > _cipherLength then 156 | return nil, "bad iv length" 157 | end 158 | 159 | if _hash.method then 160 | local tmp_key = _hash.method(key) 161 | 162 | if #tmp_key ~= _cipherLength then 163 | return nil, "bad key length" 164 | end 165 | 166 | ffi_copy(gen_key, tmp_key, _cipherLength) 167 | 168 | elseif #key ~= _cipherLength then 169 | return nil, "bad key length" 170 | 171 | else 172 | ffi_copy(gen_key, key, _cipherLength) 173 | end 174 | 175 | ffi_copy(gen_iv, _hash.iv, iv_len) 176 | 177 | else 178 | if salt and #salt ~= 8 then 179 | return nil, "salt must be 8 characters or nil" 180 | end 181 | 182 | if C.EVP_BytesToKey(_cipher.method, _hash, salt, key, #key, 183 | hash_rounds, gen_key, gen_iv) 184 | ~= _cipherLength 185 | then 186 | return nil, "failed to generate key and iv" 187 | end 188 | end 189 | 190 | if C.EVP_EncryptInit_ex(encrypt_ctx, _cipher.method, nil, 191 | nil, nil) == 0 or 192 | C.EVP_DecryptInit_ex(decrypt_ctx, _cipher.method, nil, 193 | nil, nil) == 0 then 194 | return nil, "failed to init ctx" 195 | end 196 | 197 | local cipher_name = _cipher.cipher 198 | if cipher_name == "gcm" 199 | or cipher_name == "ccm" 200 | or cipher_name == "ocb" then 201 | if C.EVP_CIPHER_CTX_ctrl(encrypt_ctx, EVP_CTRL_AEAD_SET_IVLEN, 202 | iv_len, nil) == 0 or 203 | C.EVP_CIPHER_CTX_ctrl(decrypt_ctx, EVP_CTRL_AEAD_SET_IVLEN, 204 | iv_len, nil) == 0 then 205 | return nil, "failed to set IV length" 206 | end 207 | end 208 | 209 | if C.EVP_CIPHER_CTX_set_padding(encrypt_ctx, padding) == 0 then 210 | return nil, "failed to set padding for encrypt context" 211 | end 212 | 213 | if C.EVP_CIPHER_CTX_set_padding(decrypt_ctx, padding) == 0 then 214 | return nil, "failed to set padding for decrypt context" 215 | end 216 | 217 | return setmetatable({ 218 | _encrypt_ctx = encrypt_ctx, 219 | _decrypt_ctx = decrypt_ctx, 220 | _cipher = _cipher.cipher, 221 | _key = gen_key, 222 | _iv = gen_iv 223 | }, mt) 224 | end 225 | 226 | 227 | function _M.encrypt(self, s, aad) 228 | local typ = type(self) 229 | if typ ~= "table" then 230 | error("bad argument #1 self: table expected, got " .. typ, 2) 231 | end 232 | 233 | local s_len = #s 234 | local max_len = s_len + 2 * EVP_MAX_BLOCK_LENGTH 235 | local buf = ffi_new("unsigned char[?]", max_len) 236 | local out_len = ffi_new("int[1]") 237 | local tmp_len = ffi_new("int[1]") 238 | local ctx = self._encrypt_ctx 239 | 240 | if C.EVP_EncryptInit_ex(ctx, nil, nil, self._key, self._iv) == 0 then 241 | return nil, "EVP_EncryptInit_ex failed" 242 | end 243 | 244 | if self._cipher == "gcm" and aad ~= nil then 245 | if C.EVP_EncryptUpdate(ctx, nil, tmp_len, aad, #aad) == 0 then 246 | return nil, "C.EVP_EncryptUpdate failed" 247 | end 248 | end 249 | 250 | if C.EVP_EncryptUpdate(ctx, buf, out_len, s, s_len) == 0 then 251 | return nil, "EVP_EncryptUpdate failed" 252 | end 253 | 254 | if self._cipher == "gcm" then 255 | local encrypt_data = ffi_str(buf, out_len[0]) 256 | if C.EVP_EncryptFinal_ex(ctx, buf, out_len) == 0 then 257 | return nil, "EVP_DecryptFinal_ex failed" 258 | end 259 | 260 | -- FIXME: For OCB mode the taglen must either be 16 261 | -- or the value previously set via EVP_CTRL_OCB_SET_TAGLEN. 262 | -- so we should extend this api in the future 263 | C.EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, 16, buf); 264 | local tag = ffi_str(buf, 16) 265 | return {encrypt_data, tag} 266 | end 267 | 268 | if C.EVP_EncryptFinal_ex(ctx, buf + out_len[0], tmp_len) == 0 then 269 | return nil, "EVP_EncryptFinal_ex failed" 270 | end 271 | 272 | return ffi_str(buf, out_len[0] + tmp_len[0]) 273 | end 274 | 275 | 276 | function _M.decrypt(self, s, tag, aad) 277 | local typ = type(self) 278 | if typ ~= "table" then 279 | error("bad argument #1 self: table expected, got " .. typ, 2) 280 | end 281 | 282 | local s_len = #s 283 | local max_len = s_len + 2 * EVP_MAX_BLOCK_LENGTH 284 | local buf = ffi_new("unsigned char[?]", max_len) 285 | local out_len = ffi_new("int[1]") 286 | local tmp_len = ffi_new("int[1]") 287 | local ctx = self._decrypt_ctx 288 | 289 | if C.EVP_DecryptInit_ex(ctx, nil, nil, self._key, self._iv) == 0 then 290 | return nil, "EVP_DecryptInit_ex failed" 291 | end 292 | 293 | if self._cipher == "gcm" and aad ~= nil then 294 | if C.EVP_DecryptUpdate(ctx, nil, tmp_len, aad, #aad) == 0 then 295 | return nil, "C.EVP_DecryptUpdate failed" 296 | end 297 | end 298 | 299 | if C.EVP_DecryptUpdate(ctx, buf, out_len, s, s_len) == 0 then 300 | return nil, "EVP_DecryptUpdate failed" 301 | end 302 | 303 | if self._cipher == "gcm" then 304 | local plain_txt = ffi_str(buf, out_len[0]) 305 | if tag ~= nil then 306 | local tag_buf = ffi_new("unsigned char[?]", 16) 307 | ffi.copy(tag_buf, tag, 16) 308 | C.EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, 16, tag_buf); 309 | end 310 | 311 | if C.EVP_DecryptFinal_ex(ctx, buf + out_len[0], tmp_len) == 0 then 312 | return nil, "EVP_DecryptFinal_ex failed" 313 | end 314 | 315 | return plain_txt 316 | end 317 | 318 | if C.EVP_DecryptFinal_ex(ctx, buf + out_len[0], tmp_len) == 0 then 319 | return nil, "EVP_DecryptFinal_ex failed" 320 | end 321 | 322 | return ffi_str(buf, out_len[0] + tmp_len[0]) 323 | end 324 | 325 | 326 | return _M 327 | 328 | -------------------------------------------------------------------------------- /lib/resty/md5.lua: -------------------------------------------------------------------------------- 1 | -- Copyright (C) by Yichun Zhang (agentzh) 2 | 3 | 4 | local ffi = require "ffi" 5 | local ffi_new = ffi.new 6 | local ffi_str = ffi.string 7 | local C = ffi.C 8 | local setmetatable = setmetatable 9 | --local error = error 10 | 11 | 12 | local _M = { _VERSION = '0.16' } 13 | 14 | local mt = { __index = _M } 15 | 16 | 17 | ffi.cdef[[ 18 | typedef unsigned long MD5_LONG ; 19 | 20 | enum { 21 | MD5_CBLOCK = 64, 22 | MD5_LBLOCK = MD5_CBLOCK/4 23 | }; 24 | 25 | typedef struct MD5state_st 26 | { 27 | MD5_LONG A,B,C,D; 28 | MD5_LONG Nl,Nh; 29 | MD5_LONG data[MD5_LBLOCK]; 30 | unsigned int num; 31 | } MD5_CTX; 32 | 33 | int MD5_Init(MD5_CTX *c); 34 | int MD5_Update(MD5_CTX *c, const void *data, size_t len); 35 | int MD5_Final(unsigned char *md, MD5_CTX *c); 36 | ]] 37 | 38 | local buf = ffi_new("char[16]") 39 | local ctx_ptr_type = ffi.typeof("MD5_CTX[1]") 40 | 41 | 42 | function _M.new(self) 43 | local ctx = ffi_new(ctx_ptr_type) 44 | if C.MD5_Init(ctx) == 0 then 45 | return nil 46 | end 47 | 48 | return setmetatable({ _ctx = ctx }, mt) 49 | end 50 | 51 | 52 | function _M.update(self, s, len) 53 | return C.MD5_Update(self._ctx, s, len or #s) == 1 54 | end 55 | 56 | 57 | function _M.final(self) 58 | if C.MD5_Final(buf, self._ctx) == 1 then 59 | return ffi_str(buf, 16) 60 | end 61 | 62 | return nil 63 | end 64 | 65 | 66 | function _M.reset(self) 67 | return C.MD5_Init(self._ctx) == 1 68 | end 69 | 70 | 71 | return _M 72 | 73 | -------------------------------------------------------------------------------- /lib/resty/random.lua: -------------------------------------------------------------------------------- 1 | -- Copyright (C) by Yichun Zhang (agentzh) 2 | 3 | 4 | local ffi = require "ffi" 5 | local ffi_new = ffi.new 6 | local ffi_str = ffi.string 7 | local C = ffi.C 8 | --local setmetatable = setmetatable 9 | --local error = error 10 | 11 | 12 | local _M = { _VERSION = '0.16' } 13 | 14 | 15 | ffi.cdef[[ 16 | int RAND_bytes(unsigned char *buf, int num); 17 | int RAND_pseudo_bytes(unsigned char *buf, int num); 18 | ]] 19 | 20 | 21 | function _M.bytes(len, strong) 22 | if strong == nil then 23 | strong = true 24 | end 25 | local buf = ffi_new("char[?]", len) 26 | if strong then 27 | if C.RAND_bytes(buf, len) == 0 then 28 | return nil 29 | end 30 | else 31 | C.RAND_pseudo_bytes(buf,len) 32 | end 33 | 34 | return ffi_str(buf, len) 35 | end 36 | 37 | 38 | return _M 39 | 40 | -------------------------------------------------------------------------------- /lib/resty/sha.lua: -------------------------------------------------------------------------------- 1 | -- Copyright (C) by Yichun Zhang (agentzh) 2 | 3 | 4 | local ffi = require "ffi" 5 | 6 | 7 | local _M = { _VERSION = '0.16' } 8 | 9 | 10 | ffi.cdef[[ 11 | typedef unsigned long SHA_LONG; 12 | typedef unsigned long long SHA_LONG64; 13 | 14 | enum { 15 | SHA_LBLOCK = 16 16 | }; 17 | ]]; 18 | 19 | return _M 20 | -------------------------------------------------------------------------------- /lib/resty/sha1.lua: -------------------------------------------------------------------------------- 1 | -- Copyright (C) by Yichun Zhang (agentzh) 2 | 3 | 4 | require "resty.sha" 5 | local ffi = require "ffi" 6 | local ffi_new = ffi.new 7 | local ffi_str = ffi.string 8 | local C = ffi.C 9 | local setmetatable = setmetatable 10 | --local error = error 11 | 12 | 13 | local _M = { _VERSION = '0.16' } 14 | 15 | 16 | local mt = { __index = _M } 17 | 18 | 19 | ffi.cdef[[ 20 | typedef struct SHAstate_st 21 | { 22 | SHA_LONG h0,h1,h2,h3,h4; 23 | SHA_LONG Nl,Nh; 24 | SHA_LONG data[SHA_LBLOCK]; 25 | unsigned int num; 26 | } SHA_CTX; 27 | 28 | int SHA1_Init(SHA_CTX *c); 29 | int SHA1_Update(SHA_CTX *c, const void *data, size_t len); 30 | int SHA1_Final(unsigned char *md, SHA_CTX *c); 31 | ]] 32 | 33 | local digest_len = 20 34 | 35 | local buf = ffi_new("char[?]", digest_len) 36 | local ctx_ptr_type = ffi.typeof("SHA_CTX[1]") 37 | 38 | 39 | function _M.new(self) 40 | local ctx = ffi_new(ctx_ptr_type) 41 | if C.SHA1_Init(ctx) == 0 then 42 | return nil 43 | end 44 | 45 | return setmetatable({ _ctx = ctx }, mt) 46 | end 47 | 48 | 49 | function _M.update(self, s) 50 | return C.SHA1_Update(self._ctx, s, #s) == 1 51 | end 52 | 53 | 54 | function _M.final(self) 55 | if C.SHA1_Final(buf, self._ctx) == 1 then 56 | return ffi_str(buf, digest_len) 57 | end 58 | 59 | return nil 60 | end 61 | 62 | 63 | function _M.reset(self) 64 | return C.SHA1_Init(self._ctx) == 1 65 | end 66 | 67 | 68 | return _M 69 | 70 | -------------------------------------------------------------------------------- /lib/resty/sha224.lua: -------------------------------------------------------------------------------- 1 | -- Copyright (C) by Yichun Zhang (agentzh) 2 | 3 | 4 | require "resty.sha256" 5 | local ffi = require "ffi" 6 | local ffi_new = ffi.new 7 | local ffi_str = ffi.string 8 | local C = ffi.C 9 | local setmetatable = setmetatable 10 | --local error = error 11 | 12 | 13 | local _M = { _VERSION = '0.16' } 14 | 15 | 16 | local mt = { __index = _M } 17 | 18 | 19 | ffi.cdef[[ 20 | int SHA224_Init(SHA256_CTX *c); 21 | int SHA224_Update(SHA256_CTX *c, const void *data, size_t len); 22 | int SHA224_Final(unsigned char *md, SHA256_CTX *c); 23 | ]] 24 | 25 | local digest_len = 28 26 | 27 | local buf = ffi_new("char[?]", digest_len) 28 | local ctx_ptr_type = ffi.typeof("SHA256_CTX[1]") 29 | 30 | 31 | function _M.new(self) 32 | local ctx = ffi_new(ctx_ptr_type) 33 | if C.SHA224_Init(ctx) == 0 then 34 | return nil 35 | end 36 | 37 | return setmetatable({ _ctx = ctx }, mt) 38 | end 39 | 40 | 41 | function _M.update(self, s) 42 | return C.SHA224_Update(self._ctx, s, #s) == 1 43 | end 44 | 45 | 46 | function _M.final(self) 47 | if C.SHA224_Final(buf, self._ctx) == 1 then 48 | return ffi_str(buf, digest_len) 49 | end 50 | 51 | return nil 52 | end 53 | 54 | 55 | function _M.reset(self) 56 | return C.SHA224_Init(self._ctx) == 1 57 | end 58 | 59 | 60 | return _M 61 | -------------------------------------------------------------------------------- /lib/resty/sha256.lua: -------------------------------------------------------------------------------- 1 | -- Copyright (C) by Yichun Zhang (agentzh) 2 | 3 | 4 | require "resty.sha" 5 | local ffi = require "ffi" 6 | local ffi_new = ffi.new 7 | local ffi_str = ffi.string 8 | local C = ffi.C 9 | local setmetatable = setmetatable 10 | --local error = error 11 | 12 | 13 | local _M = { _VERSION = '0.16' } 14 | 15 | 16 | local mt = { __index = _M } 17 | 18 | 19 | ffi.cdef[[ 20 | typedef struct SHA256state_st 21 | { 22 | SHA_LONG h[8]; 23 | SHA_LONG Nl,Nh; 24 | SHA_LONG data[SHA_LBLOCK]; 25 | unsigned int num,md_len; 26 | } SHA256_CTX; 27 | 28 | int SHA256_Init(SHA256_CTX *c); 29 | int SHA256_Update(SHA256_CTX *c, const void *data, size_t len); 30 | int SHA256_Final(unsigned char *md, SHA256_CTX *c); 31 | ]] 32 | 33 | local digest_len = 32 34 | 35 | local buf = ffi_new("char[?]", digest_len) 36 | local ctx_ptr_type = ffi.typeof("SHA256_CTX[1]") 37 | 38 | 39 | function _M.new(self) 40 | local ctx = ffi_new(ctx_ptr_type) 41 | if C.SHA256_Init(ctx) == 0 then 42 | return nil 43 | end 44 | 45 | return setmetatable({ _ctx = ctx }, mt) 46 | end 47 | 48 | 49 | function _M.update(self, s) 50 | return C.SHA256_Update(self._ctx, s, #s) == 1 51 | end 52 | 53 | 54 | function _M.final(self) 55 | if C.SHA256_Final(buf, self._ctx) == 1 then 56 | return ffi_str(buf, digest_len) 57 | end 58 | 59 | return nil 60 | end 61 | 62 | 63 | function _M.reset(self) 64 | return C.SHA256_Init(self._ctx) == 1 65 | end 66 | 67 | 68 | return _M 69 | 70 | -------------------------------------------------------------------------------- /lib/resty/sha384.lua: -------------------------------------------------------------------------------- 1 | -- Copyright (C) by Yichun Zhang (agentzh) 2 | 3 | 4 | require "resty.sha512" 5 | local ffi = require "ffi" 6 | local ffi_new = ffi.new 7 | local ffi_str = ffi.string 8 | local C = ffi.C 9 | local setmetatable = setmetatable 10 | --local error = error 11 | 12 | 13 | local _M = { _VERSION = '0.16' } 14 | 15 | 16 | local mt = { __index = _M } 17 | 18 | 19 | ffi.cdef[[ 20 | int SHA384_Init(SHA512_CTX *c); 21 | int SHA384_Update(SHA512_CTX *c, const void *data, size_t len); 22 | int SHA384_Final(unsigned char *md, SHA512_CTX *c); 23 | ]] 24 | 25 | local digest_len = 48 26 | 27 | local buf = ffi_new("char[?]", digest_len) 28 | local ctx_ptr_type = ffi.typeof("SHA512_CTX[1]") 29 | 30 | 31 | function _M.new(self) 32 | local ctx = ffi_new(ctx_ptr_type) 33 | if C.SHA384_Init(ctx) == 0 then 34 | return nil 35 | end 36 | 37 | return setmetatable({ _ctx = ctx }, mt) 38 | end 39 | 40 | 41 | function _M.update(self, s) 42 | return C.SHA384_Update(self._ctx, s, #s) == 1 43 | end 44 | 45 | 46 | function _M.final(self) 47 | if C.SHA384_Final(buf, self._ctx) == 1 then 48 | return ffi_str(buf, digest_len) 49 | end 50 | 51 | return nil 52 | end 53 | 54 | 55 | function _M.reset(self) 56 | return C.SHA384_Init(self._ctx) == 1 57 | end 58 | 59 | return _M 60 | 61 | -------------------------------------------------------------------------------- /lib/resty/sha512.lua: -------------------------------------------------------------------------------- 1 | -- Copyright (C) by Yichun Zhang (agentzh) 2 | 3 | 4 | require "resty.sha" 5 | local ffi = require "ffi" 6 | local ffi_new = ffi.new 7 | local ffi_str = ffi.string 8 | local C = ffi.C 9 | local setmetatable = setmetatable 10 | --local error = error 11 | 12 | 13 | local _M = { _VERSION = '0.16' } 14 | 15 | 16 | local mt = { __index = _M } 17 | 18 | 19 | ffi.cdef[[ 20 | enum { 21 | SHA512_CBLOCK = SHA_LBLOCK*8 22 | }; 23 | 24 | typedef struct SHA512state_st 25 | { 26 | SHA_LONG64 h[8]; 27 | SHA_LONG64 Nl,Nh; 28 | union { 29 | SHA_LONG64 d[SHA_LBLOCK]; 30 | unsigned char p[SHA512_CBLOCK]; 31 | } u; 32 | unsigned int num,md_len; 33 | } SHA512_CTX; 34 | 35 | int SHA512_Init(SHA512_CTX *c); 36 | int SHA512_Update(SHA512_CTX *c, const void *data, size_t len); 37 | int SHA512_Final(unsigned char *md, SHA512_CTX *c); 38 | ]] 39 | 40 | local digest_len = 64 41 | 42 | local buf = ffi_new("char[?]", digest_len) 43 | local ctx_ptr_type = ffi.typeof("SHA512_CTX[1]") 44 | 45 | 46 | function _M.new(self) 47 | local ctx = ffi_new(ctx_ptr_type) 48 | if C.SHA512_Init(ctx) == 0 then 49 | return nil 50 | end 51 | 52 | return setmetatable({ _ctx = ctx }, mt) 53 | end 54 | 55 | 56 | function _M.update(self, s) 57 | return C.SHA512_Update(self._ctx, s, #s) == 1 58 | end 59 | 60 | 61 | function _M.final(self) 62 | if C.SHA512_Final(buf, self._ctx) == 1 then 63 | return ffi_str(buf, digest_len) 64 | end 65 | 66 | return nil 67 | end 68 | 69 | 70 | function _M.reset(self) 71 | return C.SHA512_Init(self._ctx) == 1 72 | end 73 | 74 | 75 | return _M 76 | -------------------------------------------------------------------------------- /lib/resty/string.lua: -------------------------------------------------------------------------------- 1 | -- Copyright (C) by Yichun Zhang (agentzh) 2 | 3 | 4 | local ffi = require "ffi" 5 | local ffi_new = ffi.new 6 | local ffi_str = ffi.string 7 | local C = ffi.C 8 | --local setmetatable = setmetatable 9 | --local error = error 10 | local tonumber = tonumber 11 | 12 | 13 | local _M = { _VERSION = '0.16' } 14 | 15 | 16 | ffi.cdef[[ 17 | typedef unsigned char u_char; 18 | 19 | u_char * ngx_hex_dump(u_char *dst, const u_char *src, size_t len); 20 | 21 | intptr_t ngx_atoi(const unsigned char *line, size_t n); 22 | ]] 23 | 24 | local str_type = ffi.typeof("uint8_t[?]") 25 | 26 | local BUF_MAX_LEN = 1024 27 | local hex_buf = ffi_new(str_type, BUF_MAX_LEN) 28 | function _M.to_hex(s) 29 | local len = #s 30 | local buf_len = len * 2 31 | local buf 32 | if buf_len <= BUF_MAX_LEN then 33 | buf = hex_buf 34 | else 35 | buf = ffi_new(str_type, buf_len) 36 | end 37 | C.ngx_hex_dump(buf, s, len) 38 | return ffi_str(buf, buf_len) 39 | end 40 | 41 | function _M.atoi(s) 42 | return tonumber(C.ngx_atoi(s, #s)) 43 | end 44 | 45 | 46 | return _M 47 | -------------------------------------------------------------------------------- /t/aes.t: -------------------------------------------------------------------------------- 1 | # vi:ft= 2 | 3 | use Test::Nginx::Socket::Lua; 4 | 5 | repeat_each(2); 6 | 7 | plan tests => repeat_each() * (3 * blocks()); 8 | 9 | our $HttpConfig = <<'_EOC_'; 10 | lua_package_path 'lib/?.lua;;'; 11 | lua_package_cpath 'lib/?.so;;'; 12 | _EOC_ 13 | 14 | #log_level 'warn'; 15 | 16 | run_tests(); 17 | 18 | __DATA__ 19 | 20 | === TEST 1: AES default hello 21 | --- http_config eval: $::HttpConfig 22 | --- config 23 | location /t { 24 | content_by_lua ' 25 | local aes = require "resty.aes" 26 | local str = require "resty.string" 27 | local aes_default = aes:new("secret") 28 | local encrypted = aes_default:encrypt("hello") 29 | ngx.say("AES-128 CBC MD5: ", str.to_hex(encrypted)) 30 | local decrypted = aes_default:decrypt(encrypted) 31 | ngx.say(decrypted == "hello") 32 | '; 33 | } 34 | --- request 35 | GET /t 36 | --- response_body 37 | AES-128 CBC MD5: 7b47a4dbb11e2cddb2f3740c9e3a552b 38 | true 39 | --- no_error_log 40 | [error] 41 | 42 | 43 | 44 | === TEST 2: AES empty key hello 45 | --- http_config eval: $::HttpConfig 46 | --- config 47 | location /t { 48 | content_by_lua ' 49 | local aes = require "resty.aes" 50 | local str = require "resty.string" 51 | local aes_default = aes:new("") 52 | local encrypted = aes_default:encrypt("hello") 53 | ngx.say("AES-128 (empty key) CBC MD5: ", str.to_hex(encrypted)) 54 | local decrypted = aes_default:decrypt(encrypted) 55 | ngx.say(decrypted == "hello") 56 | '; 57 | } 58 | --- request 59 | GET /t 60 | --- response_body 61 | AES-128 (empty key) CBC MD5: 6cb1a35bf9d66e92c9dec684fc329746 62 | true 63 | --- no_error_log 64 | [error] 65 | 66 | 67 | 68 | === TEST 3: AES 8-byte salt 69 | --- http_config eval: $::HttpConfig 70 | --- config 71 | location /t { 72 | content_by_lua ' 73 | local aes = require "resty.aes" 74 | local str = require "resty.string" 75 | local aes_default = aes:new("secret","WhatSalt") 76 | local encrypted = aes_default:encrypt("hello") 77 | ngx.say("AES-128 (salted) CBC MD5: ", str.to_hex(encrypted)) 78 | local decrypted = aes_default:decrypt(encrypted) 79 | ngx.say(decrypted == "hello") 80 | '; 81 | } 82 | --- request 83 | GET /t 84 | --- response_body 85 | AES-128 (salted) CBC MD5: f72db89f8e19326d8da4928be106705c 86 | true 87 | --- no_error_log 88 | [error] 89 | 90 | 91 | 92 | === TEST 4: AES oversized or too short salt 93 | --- http_config eval: $::HttpConfig 94 | --- config 95 | location /t { 96 | content_by_lua ' 97 | local aes = require "resty.aes" 98 | local str = require "resty.string" 99 | local res, err = aes:new("secret","Oversized!") 100 | ngx.say(res, ", ", err) 101 | res, err = aes:new("secret","abc") 102 | ngx.say(res, ", ", err) 103 | '; 104 | } 105 | --- request 106 | GET /t 107 | --- response_body 108 | nil, salt must be 8 characters or nil 109 | nil, salt must be 8 characters or nil 110 | --- no_error_log 111 | [error] 112 | 113 | 114 | 115 | === TEST 5: AES-256 ECB SHA1 no salt 116 | --- http_config eval: $::HttpConfig 117 | --- config 118 | location /t { 119 | content_by_lua ' 120 | local aes = require "resty.aes" 121 | local str = require "resty.string" 122 | local aes_default = aes:new("secret",nil, 123 | aes.cipher(256,"ecb"),aes.hash.sha1) 124 | local encrypted = aes_default:encrypt("hello") 125 | ngx.say("AES-256 ECB SHA1: ", str.to_hex(encrypted)) 126 | local decrypted = aes_default:decrypt(encrypted) 127 | ngx.say(decrypted == "hello") 128 | '; 129 | } 130 | --- request 131 | GET /t 132 | --- response_body 133 | AES-256 ECB SHA1: 927148b31f0e89696a222489403f540d 134 | true 135 | --- no_error_log 136 | [error] 137 | 138 | 139 | 140 | === TEST 6: AES-256 ECB SHA1x5 no salt 141 | --- http_config eval: $::HttpConfig 142 | --- config 143 | location /t { 144 | content_by_lua ' 145 | local aes = require "resty.aes" 146 | local str = require "resty.string" 147 | local aes_default = aes:new("secret",nil, 148 | aes.cipher(256,"ecb"),aes.hash.sha1,5) 149 | local encrypted = aes_default:encrypt("hello") 150 | ngx.say("AES-256 ECB SHA1: ", str.to_hex(encrypted)) 151 | local decrypted = aes_default:decrypt(encrypted) 152 | ngx.say(decrypted == "hello") 153 | '; 154 | } 155 | --- request 156 | GET /t 157 | --- response_body 158 | AES-256 ECB SHA1: d1a9b6e59b8980e783df223889563bee 159 | true 160 | --- no_error_log 161 | [error] 162 | 163 | 164 | 165 | === TEST 7: AES-128 CBC custom keygen 166 | --- http_config eval: $::HttpConfig 167 | --- config 168 | location /t { 169 | content_by_lua ' 170 | local aes = require "resty.aes" 171 | local str = require "resty.string" 172 | local aes_default = aes:new("Xr4ilOzQ4PCOq3aQ0qbuaQ==",nil, 173 | aes.cipher(128,"cbc"), 174 | {iv = ngx.decode_base64("Jq5cyFTja2vfyjZoSN6muw=="), 175 | method = ngx.decode_base64}) 176 | local encrypted = aes_default:encrypt("hello") 177 | ngx.say("AES-128 CBC (custom keygen) MD5: ", str.to_hex(encrypted)) 178 | local decrypted = aes_default:decrypt(encrypted) 179 | ngx.say(decrypted == "hello") 180 | local aes_check = aes:new("secret") 181 | local encrypted_check = aes_check:encrypt("hello") 182 | ngx.say(encrypted_check == encrypted) 183 | '; 184 | } 185 | --- request 186 | GET /t 187 | --- response_body 188 | AES-128 CBC (custom keygen) MD5: 7b47a4dbb11e2cddb2f3740c9e3a552b 189 | true 190 | true 191 | --- no_error_log 192 | [error] 193 | 194 | 195 | 196 | === TEST 8: AES-128 CBC custom keygen (without method) 197 | --- http_config eval: $::HttpConfig 198 | --- config 199 | location /t { 200 | content_by_lua ' 201 | local aes = require "resty.aes" 202 | local str = require "resty.string" 203 | local aes_default = aes:new(ngx.decode_base64("Xr4ilOzQ4PCOq3aQ0qbuaQ=="),nil, 204 | aes.cipher(128,"cbc"), 205 | {iv = ngx.decode_base64("Jq5cyFTja2vfyjZoSN6muw==")}) 206 | local encrypted = aes_default:encrypt("hello") 207 | ngx.say("AES-128 CBC (custom keygen) MD5: ", str.to_hex(encrypted)) 208 | local decrypted = aes_default:decrypt(encrypted) 209 | ngx.say(decrypted == "hello") 210 | local aes_check = aes:new("secret") 211 | local encrypted_check = aes_check:encrypt("hello") 212 | ngx.say(encrypted_check == encrypted) 213 | '; 214 | } 215 | --- request 216 | GET /t 217 | --- response_body 218 | AES-128 CBC (custom keygen) MD5: 7b47a4dbb11e2cddb2f3740c9e3a552b 219 | true 220 | true 221 | --- no_error_log 222 | [error] 223 | 224 | 225 | 226 | === TEST 9: AES-128 CBC custom keygen (without method, bad key len) 227 | --- http_config eval: $::HttpConfig 228 | --- config 229 | location /t { 230 | content_by_lua ' 231 | local aes = require "resty.aes" 232 | local str = require "resty.string" 233 | 234 | local aes_default, err = aes:new("hel", nil, aes.cipher(128,"cbc"), 235 | {iv = ngx.decode_base64("Jq5cyFTja2vfyjZoSN6muw==")}) 236 | 237 | if not aes_default then 238 | ngx.say("failed to new: ", err) 239 | return 240 | end 241 | 242 | local encrypted = aes_default:encrypt("hello") 243 | ngx.say("AES-128 CBC (custom keygen) MD5: ", str.to_hex(encrypted)) 244 | local decrypted = aes_default:decrypt(encrypted) 245 | ngx.say(decrypted == "hello") 246 | local aes_check = aes:new("secret") 247 | local encrypted_check = aes_check:encrypt("hello") 248 | ngx.say(encrypted_check == encrypted) 249 | '; 250 | } 251 | --- request 252 | GET /t 253 | --- response_body 254 | failed to new: bad key length 255 | --- no_error_log 256 | [error] 257 | 258 | 259 | 260 | === TEST 10: AES-128 CBC custom keygen (without method, bad iv) 261 | --- http_config eval: $::HttpConfig 262 | --- config 263 | location /t { 264 | content_by_lua ' 265 | local aes = require "resty.aes" 266 | local str = require "resty.string" 267 | 268 | local aes_default, err = aes:new( 269 | ngx.decode_base64("Xr4ilOzQ4PCOq3aQ0qbuaQ=="), 270 | nil, 271 | aes.cipher(128,"cbc"), 272 | {iv = "helloworld&helloworld"} 273 | ) 274 | 275 | if not aes_default then 276 | ngx.say("failed to new: ", err) 277 | return 278 | end 279 | 280 | local encrypted = aes_default:encrypt("hello") 281 | ngx.say("AES-128 CBC (custom keygen) MD5: ", str.to_hex(encrypted)) 282 | local decrypted = aes_default:decrypt(encrypted) 283 | ngx.say(decrypted == "hello") 284 | local aes_check = aes:new("secret") 285 | local encrypted_check = aes_check:encrypt("hello") 286 | ngx.say(encrypted_check == encrypted) 287 | '; 288 | } 289 | --- request 290 | GET /t 291 | --- response_body 292 | failed to new: bad iv length 293 | --- no_error_log 294 | [error] 295 | 296 | 297 | 298 | === TEST 11: AES-256 GCM sha256 no salt 299 | --- http_config eval: $::HttpConfig 300 | --- config 301 | location /t { 302 | content_by_lua_block { 303 | local aes = require "resty.aes" 304 | local str = require "resty.string" 305 | local aes_default = aes:new("secret",nil, 306 | aes.cipher(256,"gcm"), aes.hash.sha256, 1, 12) 307 | local encrypted = aes_default:encrypt("hello") 308 | ngx.say("AES-256 GCM: ", str.to_hex(encrypted[1]), 309 | " tag: ", str.to_hex(encrypted[2])) 310 | local decrypted, err = aes_default:decrypt(encrypted[1], encrypted[2]) 311 | ngx.say(decrypted == "hello") 312 | } 313 | } 314 | --- request 315 | GET /t 316 | --- response_body 317 | AES-256 GCM: 4acef84443 tag: bcecc29fb0d8b5c895e21f6ea89681a2 318 | true 319 | --- no_error_log 320 | [error] 321 | 322 | 323 | 324 | === TEST 12: AES-256 GCM with iv 325 | --- http_config eval: $::HttpConfig 326 | --- config 327 | location /t { 328 | content_by_lua_block { 329 | local function from_hex(s) 330 | return (s:gsub('..', function (cc) 331 | return string.char(tonumber(cc, 16)) 332 | end)) 333 | end 334 | local aes = require "resty.aes" 335 | local str = require "resty.string" 336 | local aes_default = aes:new( 337 | from_hex("40A4510F290AD8182AF4B0260C655F8511E5B46BCA20EA191D8BC7B4D99CE95F"), 338 | nil, 339 | aes.cipher(256,"gcm"), 340 | {iv = from_hex("f31a8c01e125e4720481be05")}) 341 | local encrypted = aes_default:encrypt("13770713710") 342 | ngx.say("AES-256 GCM: ", str.to_hex(encrypted[1]), 343 | " tag: ", str.to_hex(encrypted[2])) 344 | local decrypted, err = aes_default:decrypt(encrypted[1], encrypted[2]) 345 | ngx.say(decrypted == "13770713710") 346 | } 347 | } 348 | --- request 349 | GET /t 350 | --- response_body 351 | AES-256 GCM: 755eccf6aa0cd51d55ad0c tag: 9a61f5a3cc3089bbe7de00a3dd484a1d 352 | true 353 | --- no_error_log 354 | [error] 355 | 356 | 357 | 358 | === TEST 13: AES-256 GCM sha256 no salt 359 | --- http_config eval: $::HttpConfig 360 | --- config 361 | location /t { 362 | content_by_lua_block { 363 | local aes = require "resty.aes" 364 | local str = require "resty.string" 365 | local aes_default = aes:new("secret",nil, 366 | aes.cipher(256,"gcm"), aes.hash.sha256, 1, 12) 367 | local encrypted = aes_default.encrypt("hello") 368 | } 369 | } 370 | --- request 371 | GET /t 372 | --- error_code: 500 373 | --- response_body eval 374 | qr/500 Internal Server Error/ 375 | --- error_log eval 376 | qr/\[error\] .*? lua entry thread aborted: runtime error: content_by_lua\(nginx.conf:\d+\):6: bad argument #1 self: table expected, got string/ms 377 | 378 | 379 | 380 | === TEST 14: AES-256 GCM sha256 no salt 381 | --- http_config eval: $::HttpConfig 382 | --- config 383 | location /t { 384 | content_by_lua_block { 385 | local aes = require "resty.aes" 386 | local str = require "resty.string" 387 | local aes_default = aes:new("secret",nil, 388 | aes.cipher(256,"gcm"), aes.hash.sha256, 1, 12) 389 | local encrypted = aes_default.encrypt("hello") 390 | local decrypted, err = aes_default.decrypt(encrypted[1], encrypted[2]) 391 | } 392 | } 393 | --- request 394 | GET /t 395 | --- error_code: 500 396 | --- response_body eval 397 | qr/500 Internal Server Error/ 398 | --- error_log eval 399 | qr/\[error\] .*? lua entry thread aborted: runtime error: content_by_lua\(nginx.conf:\d+\):6: bad argument #1 self: table expected, got string/ms 400 | 401 | 402 | 403 | === TEST 15: AES-256 CBC, user padding string + disable padding for aes object 404 | --- http_config eval: $::HttpConfig 405 | --- config 406 | location /t { 407 | content_by_lua_block { 408 | local aes = require "resty.aes" 409 | local str = require "resty.string" 410 | local key = ngx.decode_base64("abcdefghijklmnopqrstuvwxyz0123456789ABCDEFG=") 411 | 412 | local text = "hello" 413 | local block_size = 32 414 | local pad = block_size - #text % block_size 415 | ngx.say("pad: ", pad) 416 | local text_padded = text .. string.rep(string.char(pad), pad) 417 | 418 | local aes_256_cbc_without_padding, err = aes:new( 419 | key, nil, aes.cipher(256,"cbc"), {iv = string.sub(key, 1, 16)}, 420 | nil, nil, false 421 | ) 422 | if not aes_256_cbc_without_padding then 423 | ngx.log(ngx.WARN, err) 424 | return 425 | end 426 | 427 | local encrypted_without_aes_padding, err = aes_256_cbc_without_padding:encrypt(text_padded) 428 | if not encrypted_without_aes_padding then 429 | ngx.log(ngx.ERR, err) 430 | end 431 | ngx.say("AES-256 CBC (custom keygen, user padding with block_size=32, disable padding) HEX: ", 432 | str.to_hex(encrypted_without_aes_padding), 433 | ", len: ", string.len(encrypted_without_aes_padding)) 434 | 435 | local decrypted = aes_256_cbc_without_padding:decrypt(encrypted_without_aes_padding) 436 | local pad = string.byte(string.sub(decrypted, #decrypted)) 437 | ngx.say("pad: ", pad) 438 | 439 | local decrypted_text = string.sub(decrypted, 1, #decrypted - pad) 440 | ngx.say(decrypted_text == "hello") 441 | } 442 | } 443 | --- request 444 | GET /t 445 | --- response_body 446 | pad: 27 447 | AES-256 CBC (custom keygen, user padding with block_size=32, disable padding) HEX: eebf8ca13072beede75c595a11b7fb0beffb7ccfb03f72d08456b555610172d1, len: 32 448 | pad: 27 449 | true 450 | --- no_error_log 451 | [error] 452 | 453 | 454 | 455 | === TEST 16: AES-256 CBC, user padding string + enable padding (default) for aes object, encrypted string will be longer due to auto padding 456 | --- http_config eval: $::HttpConfig 457 | --- config 458 | location /t { 459 | content_by_lua_block { 460 | local aes = require "resty.aes" 461 | local str = require "resty.string" 462 | local key = ngx.decode_base64("abcdefghijklmnopqrstuvwxyz0123456789ABCDEFG=") 463 | 464 | local text = "hello" 465 | local block_size = 32 466 | local pad = block_size - #text % block_size 467 | ngx.say("pad: ", pad) 468 | local text_padded = text .. string.rep(string.char(pad), pad) 469 | 470 | local aes_256_cbc_with_padding, err = aes:new( 471 | key, nil, aes.cipher(256,"cbc"), {iv = string.sub(key, 1, 16)}, 472 | nil, nil, true 473 | ) 474 | if not aes_256_cbc_with_padding then 475 | ngx.log(ngx.ERR, err) 476 | return 477 | end 478 | 479 | local encrypted_with_aes_padding, err = aes_256_cbc_with_padding:encrypt(text_padded) 480 | if not encrypted_with_aes_padding then 481 | ngx.log(ngx.ERR, err) 482 | end 483 | 484 | -- padding will always be added, so `len = text_padded + padding_block_size` 485 | ngx.say("AES-256 CBC (custom keygen, user padding with block_size=32, enable padding) HEX: ", 486 | str.to_hex(encrypted_with_aes_padding), 487 | ", len: ", string.len(encrypted_with_aes_padding)) 488 | 489 | local decrypted = aes_256_cbc_with_padding:decrypt(encrypted_with_aes_padding) 490 | local pad = string.byte(string.sub(decrypted, #decrypted)) 491 | ngx.say("pad: ", pad) 492 | 493 | local decrypted_text = string.sub(decrypted, 1, #decrypted - pad) 494 | ngx.say(decrypted_text == "hello") 495 | } 496 | } 497 | --- request 498 | GET /t 499 | --- response_body 500 | pad: 27 501 | AES-256 CBC (custom keygen, user padding with block_size=32, enable padding) HEX: eebf8ca13072beede75c595a11b7fb0beffb7ccfb03f72d08456b555610172d15c54a6a02e960ce527a28c8551adfdff, len: 48 502 | pad: 27 503 | true 504 | --- no_error_log 505 | [error] 506 | 507 | 508 | 509 | === TEST 17: AES-256 CBC, string without user padding + disable padding for aes object 510 | --- http_config eval: $::HttpConfig 511 | --- config 512 | location /t { 513 | content_by_lua_block { 514 | local aes = require "resty.aes" 515 | local str = require "resty.string" 516 | local key = ngx.decode_base64("abcdefghijklmnopqrstuvwxyz0123456789ABCDEFG=") 517 | 518 | local text = "hello" 519 | local aes_256_cbc_without_padding, err = aes:new( 520 | key, nil, aes.cipher(256,"cbc"), {iv = string.sub(key, 1, 16)}, 521 | nil, nil, false 522 | ) 523 | if not aes_256_cbc_without_padding then 524 | ngx.log(ngx.WARN, err) 525 | return 526 | end 527 | 528 | local encrypted_unpadded_text, err = aes_256_cbc_without_padding:encrypt(text) 529 | if not encrypted_unpadded_text then 530 | ngx.say("ERROR: unpadded text: ", err) 531 | end 532 | 533 | local aes_256_cbc_with_padding, err = aes:new( 534 | key, nil, aes.cipher(256,"cbc"), {iv = string.sub(key, 1, 16)}, 535 | nil, nil, true 536 | ) 537 | if not aes_256_cbc_with_padding then 538 | ngx.log(ngx.ERR, err) 539 | return 540 | end 541 | 542 | local encrypted_text, err = aes_256_cbc_with_padding:encrypt(text) 543 | if not encrypted_text then 544 | ngx.log(ngx.ERR, err) 545 | return 546 | end 547 | 548 | ngx.say("AES-256 CBC (custom keygen, without user padding, enable padding) HEX: ", 549 | str.to_hex(encrypted_text), 550 | ", len: ", string.len(encrypted_text)) 551 | 552 | local decrypted = aes_256_cbc_with_padding:decrypt(encrypted_text) 553 | ngx.say(decrypted == "hello") 554 | } 555 | } 556 | --- request 557 | GET /t 558 | --- response_body 559 | ERROR: unpadded text: EVP_EncryptFinal_ex failed 560 | AES-256 CBC (custom keygen, without user padding, enable padding) HEX: 794617717c15d28cc729b983cb9d2257, len: 16 561 | true 562 | --- no_error_log 563 | [error] 564 | 565 | 566 | 567 | === TEST 18: AES-256 GCM sha256 no salt with AAD 568 | --- http_config eval: $::HttpConfig 569 | --- config 570 | location /t { 571 | content_by_lua_block { 572 | local aes = require "resty.aes" 573 | local str = require "resty.string" 574 | local aes_default = aes:new("secret",nil, 575 | aes.cipher(256,"gcm"), aes.hash.sha256, 1, 12) 576 | local encrypted = aes_default:encrypt("hello", "aad") 577 | ngx.say("AES-256 GCM: ", str.to_hex(encrypted[1]), 578 | " tag: ", str.to_hex(encrypted[2])) 579 | local decrypted, err = aes_default:decrypt(encrypted[1], encrypted[2], "aad") 580 | ngx.say(decrypted == "hello") 581 | } 582 | } 583 | --- request 584 | GET /t 585 | --- response_body 586 | AES-256 GCM: 4acef84443 tag: 46f4f3ca65395568407e15768b7526d9 587 | true 588 | --- no_error_log 589 | [error] 590 | -------------------------------------------------------------------------------- /t/aes_allocation.t: -------------------------------------------------------------------------------- 1 | # vi:ft= 2 | 3 | use Test::Nginx::Socket::Lua; 4 | 5 | repeat_each(200); 6 | 7 | plan tests => repeat_each() * (3 * blocks()); 8 | 9 | our $HttpConfig = <<'_EOC_'; 10 | lua_package_path 'lib/?.lua;;'; 11 | lua_package_cpath 'lib/?.so;;'; 12 | _EOC_ 13 | 14 | #log_level 'warn'; 15 | 16 | run_tests(); 17 | 18 | __DATA__ 19 | 20 | === TEST 1: AES buffer allocation test 21 | --- http_config eval: $::HttpConfig 22 | --- config 23 | location /t { 24 | content_by_lua ' 25 | local aes = require "resty.aes" 26 | local str = require "resty.string" 27 | local rnd = require "resty.random" 28 | local aes_default = aes:new("secretsecretsecr", nil, aes.cipher(128, "ecb")) 29 | local data = rnd.bytes(math.random(4096, 16384)) 30 | local encrypted = aes_default:encrypt(data) 31 | local decrypted = aes_default:decrypt(encrypted) 32 | ngx.say(decrypted == data) 33 | '; 34 | } 35 | --- request 36 | GET /t 37 | --- response_body 38 | true 39 | --- no_error_log 40 | [error] 41 | -------------------------------------------------------------------------------- /t/atoi.t: -------------------------------------------------------------------------------- 1 | # vi:ft= 2 | 3 | use Test::Nginx::Socket::Lua; 4 | 5 | repeat_each(2); 6 | 7 | plan tests => repeat_each() * (3 * blocks()); 8 | 9 | our $HttpConfig = <<'_EOC_'; 10 | lua_package_path 'lib/?.lua;;'; 11 | lua_package_cpath 'lib/?.so;;'; 12 | _EOC_ 13 | 14 | no_long_string(); 15 | 16 | run_tests(); 17 | 18 | __DATA__ 19 | 20 | === TEST 1: atoi 21 | --- http_config eval: $::HttpConfig 22 | --- config 23 | location /t { 24 | content_by_lua ' 25 | local str = require "resty.string" 26 | ngx.say(1 + str.atoi("32")) 27 | '; 28 | } 29 | --- request 30 | GET /t 31 | --- response_body 32 | 33 33 | --- no_error_log 34 | [error] 35 | -------------------------------------------------------------------------------- /t/md5.t: -------------------------------------------------------------------------------- 1 | # vi:ft= 2 | 3 | use Test::Nginx::Socket::Lua; 4 | 5 | repeat_each(2); 6 | 7 | plan tests => repeat_each() * (3 * blocks()); 8 | 9 | our $HttpConfig = <<'_EOC_'; 10 | lua_package_path 'lib/?.lua;;'; 11 | lua_package_cpath 'lib/?.so;;'; 12 | _EOC_ 13 | 14 | no_long_string(); 15 | 16 | run_tests(); 17 | 18 | __DATA__ 19 | 20 | === TEST 1: hello MD5 21 | --- http_config eval: $::HttpConfig 22 | --- config 23 | location /t { 24 | content_by_lua ' 25 | local resty_md5 = require "resty.md5" 26 | local str = require "resty.string" 27 | local md5 = resty_md5:new() 28 | ngx.say(md5:update("hello")) 29 | local digest = md5:final() 30 | ngx.say(digest == ngx.md5_bin("hello")) 31 | ngx.say("md5: ", str.to_hex(digest)) 32 | '; 33 | } 34 | --- request 35 | GET /t 36 | --- response_body 37 | true 38 | true 39 | md5: 5d41402abc4b2a76b9719d911017c592 40 | --- no_error_log 41 | [error] 42 | 43 | 44 | 45 | === TEST 2: MD5 incremental 46 | --- http_config eval: $::HttpConfig 47 | --- config 48 | location /t { 49 | content_by_lua ' 50 | local resty_md5 = require "resty.md5" 51 | local str = require "resty.string" 52 | local md5 = resty_md5:new() 53 | ngx.say(md5:update("hel")) 54 | ngx.say(md5:update("lo")) 55 | local digest = md5:final() 56 | ngx.say("md5: ", str.to_hex(digest)) 57 | '; 58 | } 59 | --- request 60 | GET /t 61 | --- response_body 62 | true 63 | true 64 | md5: 5d41402abc4b2a76b9719d911017c592 65 | --- no_error_log 66 | [error] 67 | 68 | 69 | 70 | === TEST 3: MD5 empty string 71 | --- http_config eval: $::HttpConfig 72 | --- config 73 | location /t { 74 | content_by_lua ' 75 | local resty_md5 = require "resty.md5" 76 | local str = require "resty.string" 77 | local md5 = resty_md5:new() 78 | ngx.say(md5:update("")) 79 | local digest = md5:final() 80 | ngx.say(digest == ngx.md5_bin("")) 81 | ngx.say("md5: ", str.to_hex(digest)) 82 | '; 83 | } 84 | --- request 85 | GET /t 86 | --- response_body 87 | true 88 | true 89 | md5: d41d8cd98f00b204e9800998ecf8427e 90 | --- no_error_log 91 | [error] 92 | 93 | 94 | 95 | === TEST 4: MD5 update with len parameter 96 | --- http_config eval: $::HttpConfig 97 | --- config 98 | location /t { 99 | content_by_lua ' 100 | local resty_md5 = require "resty.md5" 101 | local str = require "resty.string" 102 | local md5 = resty_md5:new() 103 | ngx.say(md5:update("hello", 3)) 104 | local digest = md5:final() 105 | ngx.say(digest == ngx.md5_bin("hel")) 106 | md5 = resty_md5:new() 107 | ngx.say(md5:update("hello", 3)) 108 | ngx.say(md5:update("loxxx", 2)) 109 | digest = md5:final() 110 | ngx.say(digest == ngx.md5_bin("hello")) 111 | ngx.say("md5: ", str.to_hex(digest)) 112 | '; 113 | } 114 | --- request 115 | GET /t 116 | --- response_body 117 | true 118 | true 119 | true 120 | true 121 | true 122 | md5: 5d41402abc4b2a76b9719d911017c592 123 | --- no_error_log 124 | [error] 125 | -------------------------------------------------------------------------------- /t/random.t: -------------------------------------------------------------------------------- 1 | # vi:ft= 2 | 3 | use Test::Nginx::Socket::Lua; 4 | 5 | repeat_each(2); 6 | 7 | plan tests => repeat_each() * (3 * blocks()); 8 | 9 | our $HttpConfig = <<'_EOC_'; 10 | lua_package_path 'lib/?.lua;;'; 11 | lua_package_cpath 'lib/?.so;;'; 12 | _EOC_ 13 | 14 | no_long_string(); 15 | 16 | run_tests(); 17 | 18 | __DATA__ 19 | 20 | === TEST 1: pseudo random bytes 21 | --- http_config eval: $::HttpConfig 22 | --- config 23 | location /t { 24 | content_by_lua ' 25 | local rand = require "resty.random" 26 | local str = require "resty.string" 27 | local s = rand.bytes(5) 28 | ngx.say("res: ", str.to_hex(s)) 29 | '; 30 | } 31 | --- request 32 | GET /t 33 | --- response_body_like 34 | ^res: [a-f0-9]{10}$ 35 | --- no_error_log 36 | [error] 37 | 38 | 39 | 40 | === TEST 2: strong random bytes 41 | --- http_config eval: $::HttpConfig 42 | --- config 43 | location /t { 44 | content_by_lua ' 45 | local rand = require "resty.random" 46 | local str = require "resty.string" 47 | local s = rand.bytes(5, true) 48 | ngx.say("res: ", str.to_hex(s)) 49 | '; 50 | } 51 | --- request 52 | GET /t 53 | --- response_body_like 54 | ^res: [a-f0-9]{10}$ 55 | --- no_error_log 56 | [error] 57 | -------------------------------------------------------------------------------- /t/sha1.t: -------------------------------------------------------------------------------- 1 | # vi:ft= 2 | 3 | use Test::Nginx::Socket::Lua; 4 | 5 | repeat_each(2); 6 | 7 | plan tests => repeat_each() * (3 * blocks()); 8 | 9 | our $HttpConfig = <<'_EOC_'; 10 | #lua_code_cache off; 11 | lua_package_path 'lib/?.lua;;'; 12 | lua_package_cpath 'lib/?.so;;'; 13 | _EOC_ 14 | 15 | no_long_string(); 16 | 17 | run_tests(); 18 | 19 | __DATA__ 20 | 21 | === TEST 1: hello SHA-1 22 | --- http_config eval: $::HttpConfig 23 | --- config 24 | location /t { 25 | content_by_lua ' 26 | local resty_sha1 = require "resty.sha1" 27 | local str = require "resty.string" 28 | local sha1 = resty_sha1:new() 29 | ngx.say(sha1:update("hello")) 30 | local digest = sha1:final() 31 | ngx.say(digest == ngx.sha1_bin("hello")) 32 | ngx.say("sha1: ", str.to_hex(digest)) 33 | '; 34 | } 35 | --- request 36 | GET /t 37 | --- response_body 38 | true 39 | true 40 | sha1: aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d 41 | --- no_error_log 42 | [error] 43 | 44 | 45 | 46 | === TEST 2: SHA-1 incremental 47 | --- http_config eval: $::HttpConfig 48 | --- config 49 | location /t { 50 | content_by_lua ' 51 | local resty_sha1 = require "resty.sha1" 52 | local str = require "resty.string" 53 | local sha1 = resty_sha1:new() 54 | ngx.say(sha1:update("hel")) 55 | ngx.say(sha1:update("lo")) 56 | local digest = sha1:final() 57 | ngx.say("sha1: ", str.to_hex(digest)) 58 | '; 59 | } 60 | --- request 61 | GET /t 62 | --- response_body 63 | true 64 | true 65 | sha1: aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d 66 | --- no_error_log 67 | [error] 68 | 69 | 70 | 71 | === TEST 3: SHA-1 empty string 72 | --- http_config eval: $::HttpConfig 73 | --- config 74 | location /t { 75 | content_by_lua ' 76 | local resty_sha1 = require "resty.sha1" 77 | local str = require "resty.string" 78 | local sha1 = resty_sha1:new() 79 | ngx.say(sha1:update("")) 80 | local digest = sha1:final() 81 | ngx.say(digest == ngx.sha1_bin("")) 82 | ngx.say("sha1: ", str.to_hex(digest)) 83 | '; 84 | } 85 | --- request 86 | GET /t 87 | --- response_body 88 | true 89 | true 90 | sha1: da39a3ee5e6b4b0d3255bfef95601890afd80709 91 | --- no_error_log 92 | [error] 93 | -------------------------------------------------------------------------------- /t/sha224.t: -------------------------------------------------------------------------------- 1 | # vi:ft= 2 | 3 | use Test::Nginx::Socket::Lua; 4 | 5 | repeat_each(2); 6 | 7 | plan tests => repeat_each() * (3 * blocks()); 8 | 9 | our $HttpConfig = <<'_EOC_'; 10 | #lua_code_cache off; 11 | lua_package_path 'lib/?.lua;;'; 12 | lua_package_cpath 'lib/?.so;;'; 13 | _EOC_ 14 | 15 | no_long_string(); 16 | 17 | run_tests(); 18 | 19 | __DATA__ 20 | 21 | === TEST 1: hello SHA-224 22 | --- http_config eval: $::HttpConfig 23 | --- config 24 | location /t { 25 | content_by_lua ' 26 | local resty_sha224 = require "resty.sha224" 27 | local str = require "resty.string" 28 | local sha224 = resty_sha224:new() 29 | ngx.say(sha224:update("hello")) 30 | local digest = sha224:final() 31 | ngx.say("sha224: ", str.to_hex(digest)) 32 | '; 33 | } 34 | --- request 35 | GET /t 36 | --- response_body 37 | true 38 | sha224: ea09ae9cc6768c50fcee903ed054556e5bfc8347907f12598aa24193 39 | --- no_error_log 40 | [error] 41 | 42 | 43 | 44 | === TEST 2: SHA-224 incremental 45 | --- http_config eval: $::HttpConfig 46 | --- config 47 | location /t { 48 | content_by_lua ' 49 | local resty_sha224 = require "resty.sha224" 50 | local str = require "resty.string" 51 | local sha224 = resty_sha224:new() 52 | ngx.say(sha224:update("hel")) 53 | ngx.say(sha224:update("lo")) 54 | local digest = sha224:final() 55 | ngx.say("sha224: ", str.to_hex(digest)) 56 | '; 57 | } 58 | --- request 59 | GET /t 60 | --- response_body 61 | true 62 | true 63 | sha224: ea09ae9cc6768c50fcee903ed054556e5bfc8347907f12598aa24193 64 | --- no_error_log 65 | [error] 66 | 67 | 68 | 69 | === TEST 3: SHA-224 empty string 70 | --- http_config eval: $::HttpConfig 71 | --- config 72 | location /t { 73 | content_by_lua ' 74 | local resty_sha224 = require "resty.sha224" 75 | local str = require "resty.string" 76 | local sha224 = resty_sha224:new() 77 | ngx.say(sha224:update("")) 78 | local digest = sha224:final() 79 | ngx.say("sha224: ", str.to_hex(digest)) 80 | '; 81 | } 82 | --- request 83 | GET /t 84 | --- response_body 85 | true 86 | sha224: d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f 87 | --- no_error_log 88 | [error] 89 | 90 | 91 | 92 | === TEST 4: hello (SHA-1 + SHA-224 + SHA-256 + SHA-512 at the same time) 93 | --- http_config eval: $::HttpConfig 94 | --- config 95 | location /t { 96 | content_by_lua ' 97 | local resty_sha224 = require "resty.sha224" 98 | local resty_sha256 = require "resty.sha256" 99 | local resty_sha1 = require "resty.sha1" 100 | local resty_sha512 = require "resty.sha512" 101 | 102 | local str = require "resty.string" 103 | 104 | local sha224 = resty_sha224:new() 105 | local sha256 = resty_sha256:new() 106 | local sha1 = resty_sha1:new() 107 | local sha512 = resty_sha512:new() 108 | 109 | ngx.say(sha224:update("hello")) 110 | ngx.say(sha256:update("hello")) 111 | ngx.say(sha1:update("hello")) 112 | ngx.say(sha512:update("hello")) 113 | 114 | 115 | local digest = sha224:final() 116 | ngx.say("sha224: ", str.to_hex(digest)) 117 | 118 | digest = sha256:final() 119 | ngx.say("sha256: ", str.to_hex(digest)) 120 | 121 | digest = sha1:final() 122 | ngx.say("sha1: ", str.to_hex(digest)) 123 | 124 | digest = sha512:final() 125 | ngx.say("sha512: ", str.to_hex(digest)) 126 | '; 127 | } 128 | --- request 129 | GET /t 130 | --- response_body 131 | true 132 | true 133 | true 134 | true 135 | sha224: ea09ae9cc6768c50fcee903ed054556e5bfc8347907f12598aa24193 136 | sha256: 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824 137 | sha1: aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d 138 | sha512: 9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043 139 | --- no_error_log 140 | [error] 141 | -------------------------------------------------------------------------------- /t/sha256.t: -------------------------------------------------------------------------------- 1 | # vi:ft= 2 | 3 | use Test::Nginx::Socket::Lua; 4 | 5 | repeat_each(2); 6 | 7 | plan tests => repeat_each() * (3 * blocks()); 8 | 9 | our $HttpConfig = <<'_EOC_'; 10 | #lua_code_cache off; 11 | lua_package_path 'lib/?.lua;;'; 12 | lua_package_cpath 'lib/?.so;;'; 13 | _EOC_ 14 | 15 | no_long_string(); 16 | 17 | run_tests(); 18 | 19 | __DATA__ 20 | 21 | === TEST 1: hello SHA-256 22 | --- http_config eval: $::HttpConfig 23 | --- config 24 | location /t { 25 | content_by_lua ' 26 | local resty_sha256 = require "resty.sha256" 27 | local str = require "resty.string" 28 | local sha256 = resty_sha256:new() 29 | ngx.say(sha256:update("hello")) 30 | local digest = sha256:final() 31 | ngx.say("sha256: ", str.to_hex(digest)) 32 | '; 33 | } 34 | --- request 35 | GET /t 36 | --- response_body 37 | true 38 | sha256: 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824 39 | --- no_error_log 40 | [error] 41 | 42 | 43 | 44 | === TEST 2: SHA-256 incremental 45 | --- http_config eval: $::HttpConfig 46 | --- config 47 | location /t { 48 | content_by_lua ' 49 | local resty_sha256 = require "resty.sha256" 50 | local str = require "resty.string" 51 | local sha256 = resty_sha256:new() 52 | ngx.say(sha256:update("hel")) 53 | ngx.say(sha256:update("lo")) 54 | local digest = sha256:final() 55 | ngx.say("sha256: ", str.to_hex(digest)) 56 | '; 57 | } 58 | --- request 59 | GET /t 60 | --- response_body 61 | true 62 | true 63 | sha256: 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824 64 | --- no_error_log 65 | [error] 66 | 67 | 68 | 69 | === TEST 3: SHA-256 empty string 70 | --- http_config eval: $::HttpConfig 71 | --- config 72 | location /t { 73 | content_by_lua ' 74 | local resty_sha256 = require "resty.sha256" 75 | local str = require "resty.string" 76 | local sha256 = resty_sha256:new() 77 | ngx.say(sha256:update("")) 78 | local digest = sha256:final() 79 | ngx.say("sha256: ", str.to_hex(digest)) 80 | '; 81 | } 82 | --- request 83 | GET /t 84 | --- response_body 85 | true 86 | sha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 87 | --- no_error_log 88 | [error] 89 | -------------------------------------------------------------------------------- /t/sha384.t: -------------------------------------------------------------------------------- 1 | # vi:ft= 2 | 3 | use Test::Nginx::Socket; 4 | 5 | repeat_each(2); 6 | 7 | plan tests => repeat_each() * (3 * blocks()); 8 | 9 | our $HttpConfig = <<'_EOC_'; 10 | #lua_code_cache off; 11 | lua_package_path 'lib/?.lua;;'; 12 | lua_package_cpath 'lib/?.so;;'; 13 | _EOC_ 14 | 15 | no_long_string(); 16 | 17 | run_tests(); 18 | 19 | __DATA__ 20 | 21 | === TEST 1: hello SHA-384 22 | --- http_config eval: $::HttpConfig 23 | --- config 24 | location /t { 25 | content_by_lua ' 26 | local resty_sha384 = require "resty.sha384" 27 | local str = require "resty.string" 28 | local sha384 = resty_sha384:new() 29 | ngx.say(sha384:update("hello")) 30 | local digest = sha384:final() 31 | ngx.say("sha384: ", str.to_hex(digest)) 32 | '; 33 | } 34 | --- request 35 | GET /t 36 | --- response_body 37 | true 38 | sha384: 59e1748777448c69de6b800d7a33bbfb9ff1b463e44354c3553bcdb9c666fa90125a3c79f90397bdf5f6a13de828684f 39 | --- no_error_log 40 | [error] 41 | 42 | 43 | 44 | === TEST 2: SHA-384 incremental 45 | --- http_config eval: $::HttpConfig 46 | --- config 47 | location /t { 48 | content_by_lua ' 49 | local resty_sha384 = require "resty.sha384" 50 | local str = require "resty.string" 51 | local sha384 = resty_sha384:new() 52 | ngx.say(sha384:update("hel")) 53 | ngx.say(sha384:update("lo")) 54 | local digest = sha384:final() 55 | ngx.say("sha384: ", str.to_hex(digest)) 56 | '; 57 | } 58 | --- request 59 | GET /t 60 | --- response_body 61 | true 62 | true 63 | sha384: 59e1748777448c69de6b800d7a33bbfb9ff1b463e44354c3553bcdb9c666fa90125a3c79f90397bdf5f6a13de828684f 64 | --- no_error_log 65 | [error] 66 | 67 | 68 | 69 | === TEST 3: SHA-384 empty string 70 | --- http_config eval: $::HttpConfig 71 | --- config 72 | location /t { 73 | content_by_lua ' 74 | local resty_sha384 = require "resty.sha384" 75 | local str = require "resty.string" 76 | local sha384 = resty_sha384:new() 77 | ngx.say(sha384:update("")) 78 | local digest = sha384:final() 79 | ngx.say("sha384: ", str.to_hex(digest)) 80 | '; 81 | } 82 | --- request 83 | GET /t 84 | --- response_body 85 | true 86 | sha384: 38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b 87 | --- no_error_log 88 | [error] 89 | -------------------------------------------------------------------------------- /t/sha512.t: -------------------------------------------------------------------------------- 1 | # vi:ft= 2 | 3 | use Test::Nginx::Socket::Lua; 4 | 5 | repeat_each(2); 6 | 7 | plan tests => repeat_each() * (3 * blocks()); 8 | 9 | our $HttpConfig = <<'_EOC_'; 10 | #lua_code_cache off; 11 | lua_package_path 'lib/?.lua;;'; 12 | lua_package_cpath 'lib/?.so;;'; 13 | _EOC_ 14 | 15 | no_long_string(); 16 | 17 | run_tests(); 18 | 19 | __DATA__ 20 | 21 | === TEST 1: hello SHA-512 22 | --- http_config eval: $::HttpConfig 23 | --- config 24 | location /t { 25 | content_by_lua ' 26 | local resty_sha512 = require "resty.sha512" 27 | local str = require "resty.string" 28 | local sha512 = resty_sha512:new() 29 | ngx.say(sha512:update("hello")) 30 | local digest = sha512:final() 31 | ngx.say("sha512: ", str.to_hex(digest)) 32 | '; 33 | } 34 | --- request 35 | GET /t 36 | --- response_body 37 | true 38 | sha512: 9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043 39 | --- no_error_log 40 | [error] 41 | 42 | 43 | 44 | === TEST 2: SHA-512 incremental 45 | --- http_config eval: $::HttpConfig 46 | --- config 47 | location /t { 48 | content_by_lua ' 49 | local resty_sha512 = require "resty.sha512" 50 | local str = require "resty.string" 51 | local sha512 = resty_sha512:new() 52 | ngx.say(sha512:update("hel")) 53 | ngx.say(sha512:update("lo")) 54 | local digest = sha512:final() 55 | ngx.say("sha512: ", str.to_hex(digest)) 56 | '; 57 | } 58 | --- request 59 | GET /t 60 | --- response_body 61 | true 62 | true 63 | sha512: 9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043 64 | --- no_error_log 65 | [error] 66 | 67 | 68 | 69 | === TEST 3: SHA-512 empty string 70 | --- http_config eval: $::HttpConfig 71 | --- config 72 | location /t { 73 | content_by_lua ' 74 | local resty_sha512 = require "resty.sha512" 75 | local str = require "resty.string" 76 | local sha512 = resty_sha512:new() 77 | ngx.say(sha512:update("")) 78 | local digest = sha512:final() 79 | ngx.say("sha512: ", str.to_hex(digest)) 80 | '; 81 | } 82 | --- request 83 | GET /t 84 | --- response_body 85 | true 86 | sha512: cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e 87 | --- no_error_log 88 | [error] 89 | -------------------------------------------------------------------------------- /t/version.t: -------------------------------------------------------------------------------- 1 | # vim:set ft= ts=4 sw=4 et: 2 | 3 | use Test::Nginx::Socket::Lua; 4 | use Cwd qw(cwd); 5 | 6 | repeat_each(2); 7 | 8 | plan tests => repeat_each() * (3 * blocks()); 9 | 10 | my $pwd = cwd(); 11 | 12 | our $HttpConfig = qq{ 13 | lua_package_path "$pwd/lib/?.lua;;"; 14 | }; 15 | 16 | $ENV{TEST_NGINX_RESOLVER} = '8.8.8.8'; 17 | 18 | no_long_string(); 19 | #no_diff(); 20 | 21 | run_tests(); 22 | 23 | __DATA__ 24 | 25 | === TEST 1: sha1 version 26 | --- http_config eval: $::HttpConfig 27 | --- config 28 | location /t { 29 | content_by_lua ' 30 | local sha1 = require "resty.sha1" 31 | ngx.say(sha1._VERSION) 32 | '; 33 | } 34 | --- request 35 | GET /t 36 | --- response_body_like chop 37 | ^\d+\.\d+$ 38 | --- no_error_log 39 | [error] 40 | 41 | 42 | 43 | === TEST 2: md5 version 44 | --- http_config eval: $::HttpConfig 45 | --- config 46 | location /t { 47 | content_by_lua ' 48 | local md5 = require "resty.md5" 49 | ngx.say(md5._VERSION) 50 | '; 51 | } 52 | --- request 53 | GET /t 54 | --- response_body_like chop 55 | ^\d+\.\d+$ 56 | --- no_error_log 57 | [error] 58 | 59 | 60 | 61 | === TEST 3: resty.string version 62 | --- http_config eval: $::HttpConfig 63 | --- config 64 | location /t { 65 | content_by_lua ' 66 | local str = require "resty.string" 67 | ngx.say(str._VERSION) 68 | '; 69 | } 70 | --- request 71 | GET /t 72 | --- response_body_like chop 73 | ^\d+\.\d+$ 74 | --- no_error_log 75 | [error] 76 | 77 | 78 | 79 | === TEST 4: resty.random version 80 | --- http_config eval: $::HttpConfig 81 | --- config 82 | location /t { 83 | content_by_lua ' 84 | local rand = require "resty.random" 85 | ngx.say(rand._VERSION) 86 | '; 87 | } 88 | --- request 89 | GET /t 90 | --- response_body_like chop 91 | ^\d+\.\d+$ 92 | --- no_error_log 93 | [error] 94 | 95 | 96 | 97 | === TEST 5: resty.aes version 98 | --- http_config eval: $::HttpConfig 99 | --- config 100 | location /t { 101 | content_by_lua ' 102 | local aes = require "resty.aes" 103 | ngx.say(aes._VERSION) 104 | '; 105 | } 106 | --- request 107 | GET /t 108 | --- response_body_like chop 109 | ^\d+\.\d+$ 110 | --- no_error_log 111 | [error] 112 | -------------------------------------------------------------------------------- /valgrind.suppress: -------------------------------------------------------------------------------- 1 | { 2 | 3 | Memcheck:Param 4 | write(buf) 5 | fun:__write_nocancel 6 | fun:ngx_log_error_core 7 | fun:ngx_resolver_read_response 8 | } 9 | { 10 | 11 | Memcheck:Cond 12 | fun:ngx_sprintf_num 13 | fun:ngx_vslprintf 14 | fun:ngx_log_error_core 15 | fun:ngx_resolver_read_response 16 | fun:ngx_epoll_process_events 17 | fun:ngx_process_events_and_timers 18 | fun:ngx_single_process_cycle 19 | fun:main 20 | } 21 | { 22 | 23 | Memcheck:Addr1 24 | fun:ngx_vslprintf 25 | fun:ngx_snprintf 26 | fun:ngx_sock_ntop 27 | fun:ngx_event_accept 28 | } 29 | { 30 | 31 | Memcheck:Param 32 | write(buf) 33 | fun:__write_nocancel 34 | fun:ngx_log_error_core 35 | fun:ngx_resolver_read_response 36 | fun:ngx_event_process_posted 37 | fun:ngx_process_events_and_timers 38 | fun:ngx_single_process_cycle 39 | fun:main 40 | } 41 | { 42 | 43 | Memcheck:Cond 44 | fun:ngx_sprintf_num 45 | fun:ngx_vslprintf 46 | fun:ngx_log_error_core 47 | fun:ngx_resolver_read_response 48 | fun:ngx_event_process_posted 49 | fun:ngx_process_events_and_timers 50 | fun:ngx_single_process_cycle 51 | fun:main 52 | } 53 | { 54 | 55 | Memcheck:Leak 56 | fun:malloc 57 | fun:ngx_alloc 58 | obj:* 59 | } 60 | { 61 | 62 | exp-sgcheck:SorG 63 | fun:ngx_http_lua_ndk_set_var_get 64 | } 65 | { 66 | 67 | exp-sgcheck:SorG 68 | fun:ngx_http_variables_init_vars 69 | fun:ngx_http_block 70 | } 71 | { 72 | 73 | exp-sgcheck:SorG 74 | fun:ngx_conf_parse 75 | } 76 | { 77 | 78 | exp-sgcheck:SorG 79 | fun:ngx_vslprintf 80 | fun:ngx_log_error_core 81 | } 82 | { 83 | 84 | Memcheck:Leak 85 | fun:malloc 86 | fun:ngx_alloc 87 | fun:ngx_calloc 88 | fun:ngx_event_process_init 89 | } 90 | { 91 | 92 | Memcheck:Param 93 | epoll_ctl(event) 94 | fun:epoll_ctl 95 | } 96 | { 97 | 98 | Memcheck:Leak 99 | fun:malloc 100 | fun:ngx_alloc 101 | fun:ngx_event_process_init 102 | } 103 | { 104 | 105 | Memcheck:Cond 106 | fun:ngx_conf_flush_files 107 | fun:ngx_single_process_cycle 108 | } 109 | { 110 | 111 | Memcheck:Cond 112 | fun:memcpy 113 | fun:ngx_vslprintf 114 | fun:ngx_log_error_core 115 | fun:ngx_http_charset_header_filter 116 | } 117 | { 118 | 119 | Memcheck:Param 120 | socketcall.setsockopt(optval) 121 | fun:setsockopt 122 | fun:drizzle_state_connect 123 | } 124 | { 125 | 126 | Memcheck:Leak 127 | fun:malloc 128 | fun:ngx_alloc 129 | fun:ngx_pool_cleanup_add 130 | } 131 | { 132 | 133 | Memcheck:Cond 134 | fun:ngx_conf_flush_files 135 | fun:ngx_single_process_cycle 136 | fun:main 137 | } 138 | { 139 | 140 | Memcheck:Leak 141 | fun:malloc 142 | fun:ngx_alloc 143 | fun:ngx_palloc_large 144 | fun:ngx_palloc 145 | fun:ngx_array_push 146 | fun:ngx_http_get_variable_index 147 | fun:ngx_http_memc_add_variable 148 | fun:ngx_http_memc_init 149 | fun:ngx_http_block 150 | fun:ngx_conf_parse 151 | fun:ngx_init_cycle 152 | fun:main 153 | } 154 | { 155 | 156 | Memcheck:Leak 157 | fun:malloc 158 | fun:ngx_alloc 159 | fun:ngx_event_process_init 160 | fun:ngx_single_process_cycle 161 | fun:main 162 | } 163 | { 164 | 165 | Memcheck:Leak 166 | fun:malloc 167 | fun:ngx_alloc 168 | fun:ngx_crc32_table_init 169 | fun:main 170 | } 171 | { 172 | 173 | Memcheck:Leak 174 | fun:malloc 175 | fun:ngx_alloc 176 | fun:ngx_event_process_init 177 | fun:ngx_worker_process_init 178 | fun:ngx_worker_process_cycle 179 | fun:ngx_spawn_process 180 | fun:ngx_start_worker_processes 181 | fun:ngx_master_process_cycle 182 | fun:main 183 | } 184 | { 185 | 186 | Memcheck:Leak 187 | fun:malloc 188 | fun:ngx_alloc 189 | fun:ngx_palloc_large 190 | fun:ngx_palloc 191 | fun:ngx_pcalloc 192 | fun:ngx_hash_init 193 | fun:ngx_http_variables_init_vars 194 | fun:ngx_http_block 195 | fun:ngx_conf_parse 196 | fun:ngx_init_cycle 197 | fun:main 198 | } 199 | { 200 | 201 | Memcheck:Leak 202 | fun:malloc 203 | fun:ngx_alloc 204 | fun:ngx_palloc_large 205 | fun:ngx_palloc 206 | fun:ngx_pcalloc 207 | fun:ngx_http_upstream_drizzle_create_srv_conf 208 | fun:ngx_http_upstream 209 | fun:ngx_conf_parse 210 | fun:ngx_http_block 211 | fun:ngx_conf_parse 212 | fun:ngx_init_cycle 213 | fun:main 214 | } 215 | { 216 | 217 | Memcheck:Leak 218 | fun:malloc 219 | fun:ngx_alloc 220 | fun:ngx_palloc_large 221 | fun:ngx_palloc 222 | fun:ngx_pcalloc 223 | fun:ngx_hash_keys_array_init 224 | fun:ngx_http_variables_add_core_vars 225 | fun:ngx_http_core_preconfiguration 226 | fun:ngx_http_block 227 | fun:ngx_conf_parse 228 | fun:ngx_init_cycle 229 | fun:main 230 | } 231 | { 232 | 233 | Memcheck:Leak 234 | fun:malloc 235 | fun:ngx_alloc 236 | fun:ngx_palloc_large 237 | fun:ngx_palloc 238 | fun:ngx_array_push 239 | fun:ngx_hash_add_key 240 | fun:ngx_http_add_variable 241 | fun:ngx_http_echo_add_variables 242 | fun:ngx_http_echo_handler_init 243 | fun:ngx_http_block 244 | fun:ngx_conf_parse 245 | fun:ngx_init_cycle 246 | } 247 | { 248 | 249 | Memcheck:Leak 250 | fun:malloc 251 | fun:ngx_alloc 252 | fun:ngx_palloc_large 253 | fun:ngx_palloc 254 | fun:ngx_pcalloc 255 | fun:ngx_http_upstream_drizzle_create_srv_conf 256 | fun:ngx_http_core_server 257 | fun:ngx_conf_parse 258 | fun:ngx_http_block 259 | fun:ngx_conf_parse 260 | fun:ngx_init_cycle 261 | fun:main 262 | } 263 | { 264 | 265 | Memcheck:Leak 266 | fun:malloc 267 | fun:ngx_alloc 268 | fun:ngx_palloc_large 269 | fun:ngx_palloc 270 | fun:ngx_pcalloc 271 | fun:ngx_http_upstream_drizzle_create_srv_conf 272 | fun:ngx_http_block 273 | fun:ngx_conf_parse 274 | fun:ngx_init_cycle 275 | fun:main 276 | } 277 | { 278 | 279 | Memcheck:Leak 280 | fun:malloc 281 | fun:ngx_alloc 282 | fun:ngx_palloc_large 283 | fun:ngx_palloc 284 | fun:ngx_array_push 285 | fun:ngx_hash_add_key 286 | fun:ngx_http_variables_add_core_vars 287 | fun:ngx_http_core_preconfiguration 288 | fun:ngx_http_block 289 | fun:ngx_conf_parse 290 | fun:ngx_init_cycle 291 | fun:main 292 | } 293 | { 294 | 295 | Memcheck:Leak 296 | fun:malloc 297 | fun:ngx_alloc 298 | fun:ngx_palloc_large 299 | fun:ngx_palloc 300 | fun:ngx_pcalloc 301 | fun:ngx_init_cycle 302 | fun:main 303 | } 304 | { 305 | 306 | Memcheck:Leak 307 | fun:malloc 308 | fun:ngx_alloc 309 | fun:ngx_palloc_large 310 | fun:ngx_palloc 311 | fun:ngx_hash_init 312 | fun:ngx_http_upstream_init_main_conf 313 | fun:ngx_http_block 314 | fun:ngx_conf_parse 315 | fun:ngx_init_cycle 316 | fun:main 317 | } 318 | { 319 | 320 | Memcheck:Leak 321 | fun:malloc 322 | fun:ngx_alloc 323 | fun:ngx_palloc_large 324 | fun:ngx_palloc 325 | fun:ngx_pcalloc 326 | fun:ngx_http_drizzle_keepalive_init 327 | fun:ngx_http_upstream_drizzle_init 328 | fun:ngx_http_upstream_init_main_conf 329 | fun:ngx_http_block 330 | fun:ngx_conf_parse 331 | fun:ngx_init_cycle 332 | fun:main 333 | } 334 | { 335 | 336 | Memcheck:Leak 337 | fun:malloc 338 | fun:ngx_alloc 339 | fun:ngx_palloc_large 340 | fun:ngx_palloc 341 | fun:ngx_hash_init 342 | fun:ngx_http_variables_init_vars 343 | fun:ngx_http_block 344 | fun:ngx_conf_parse 345 | fun:ngx_init_cycle 346 | fun:main 347 | } 348 | { 349 | 350 | Memcheck:Cond 351 | fun:index 352 | fun:expand_dynamic_string_token 353 | fun:_dl_map_object 354 | fun:map_doit 355 | fun:_dl_catch_error 356 | fun:do_preload 357 | fun:dl_main 358 | fun:_dl_sysdep_start 359 | fun:_dl_start 360 | } 361 | { 362 | 363 | Memcheck:Leak 364 | match-leak-kinds: definite 365 | fun:malloc 366 | fun:ngx_alloc 367 | fun:ngx_set_environment 368 | fun:ngx_single_process_cycle 369 | } 370 | { 371 | 372 | Memcheck:Leak 373 | match-leak-kinds: definite 374 | fun:malloc 375 | fun:ngx_alloc 376 | fun:ngx_set_environment 377 | fun:ngx_worker_process_init 378 | fun:ngx_worker_process_cycle 379 | } 380 | --------------------------------------------------------------------------------