Skip to content
Permalink
Browse files

initial commit

  • Loading branch information...
fffonion committed Sep 25, 2019
0 parents commit ec0bb305d408490e1b249f64189b21ff6c7b89a4
@@ -0,0 +1 @@
t/servroot
@@ -0,0 +1,68 @@
sudo: required
dist: trusty

os: linux

language: c
compiler:
- gcc
- clang

cache:
directories:
- download-cache

env:
global:
- JOBS=3
- SH=bash
- NGX_BUILD_JOBS=$JOBS
- LUAJIT_PREFIX=/opt/luajit21
- LUAJIT_LIB=$LUAJIT_PREFIX/lib
- LUAJIT_INC=$LUAJIT_PREFIX/include/luajit-2.1
- LUA_INCLUDE_DIR=$LUAJIT_INC
- OPENSSL_PREFIX=/opt/ssl
- OPENSSL_LIB=$OPENSSL_PREFIX/lib
- OPENSSL_INC=$OPENSSL_PREFIX/include
- LD_LIBRARY_PATH=$LUAJIT_LIB:$LD_LIBRARY_PATH
- TEST_NGINX_SLEEP=0.005
- TEST_NGINX_RANDOMIZE=1
- LUACHECK_VER=0.21.1
matrix:
- NGINX_VERSION=1.15.8 OPENSSL_VER=1.0.2t
- NGINX_VERSION=1.15.8 OPENSSL_VER=1.1.0l
- NGINX_VERSION=1.15.8 OPENSSL_VER=1.1.1d

install:
- export NGX_BUILD_CC=$CC
- export PATH=$PWD/work/nginx/sbin:$PWD/nginx-devel-utils:$PATH
- sudo apt-get install -qq -y cpanminus axel
- sudo cpanm --notest Test::Nginx > build.log 2>&1 || (cat build.log && exit 1)
- git clone https://github.com/openresty/openresty.git ../openresty
- git clone https://github.com/openresty/nginx-devel-utils.git
- git clone https://github.com/simpl/ngx_devel_kit.git ../ndk-nginx-module
- git clone https://github.com/openresty/lua-nginx-module.git ../lua-nginx-module
- git clone https://github.com/openresty/lua-resty-core.git ../lua-resty-core
- git clone https://github.com/openresty/no-pool-nginx.git ../no-pool-nginx
- git clone https://github.com/openresty/lua-resty-lrucache.git ../lua-resty-lrucache
# luajit
- git clone -b v2.1-agentzh https://github.com/openresty/luajit2.git
- pushd luajit2/
- 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)
- make install PREFIX=$LUAJIT_PREFIX > build.log 2>&1 || (cat build.log && exit 1)
- popd
# openssl
- 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
- tar zxf download-cache/openssl-$OPENSSL_VER.tar.gz
- pushd openssl-$OPENSSL_VER/
- ./config shared --prefix=$OPENSSL_PREFIX -DPURIFY > build.log 2>&1 || (cat build.log && exit 1)
- make -j$JOBS > build.log 2>&1 || (cat build.log && exit 1)
- sudo make PATH=$PATH install_sw > build.log 2>&1 || (cat build.log && exit 1)
- popd
# nginx
- ngx-build $NGINX_VERSION --add-module=../ndk-nginx-module --add-module=../lua-nginx-module --with-http_ssl_module --with-cc-opt="-I$OPENSSL_INC" --with-ld-opt="-L$OPENSSL_LIB -Wl,-rpath,$OPENSSL_LIB" --with-debug > build.log 2>&1 || (cat build.log && exit 1)
- nginx -V
- ldd `which nginx`|grep -E 'luajit|ssl|pcre'

script:
- prove -j$JOBS -r t/
@@ -0,0 +1,21 @@
OPENRESTY_PREFIX=/usr/local/openresty

#LUA_VERSION := 5.1
PREFIX ?= /usr/local
LUA_INCLUDE_DIR ?= $(PREFIX)/include
LUA_LIB_DIR ?= $(PREFIX)/lib/lua/$(LUA_VERSION)
INSTALL ?= install

.PHONY: all test install

all: ;

install: all
$(INSTALL) -d $(DESTDIR)$(LUA_LIB_DIR)/resty/openssl
$(INSTALL) lib/resty/openssl*.lua $(DESTDIR)$(LUA_LIB_DIR)/resty/
$(INSTALL) lib/resty/openssl/*.lua $(DESTDIR)$(LUA_LIB_DIR)/resty/openssl/

test: all
PATH=$(OPENRESTY_PREFIX)/nginx/sbin:$$PATH prove -I../test-nginx/lib -r t


@@ -0,0 +1,66 @@
# lua-resty-acme

FFI-based OpenSSL binding for LuaJIT, support OpenSSL 1.1 and 1.0.2 series

![Build Status](https://travis-ci.org/fffonion/lua-resty-openssl.svg?branch=master)


Table of Contents
=================

- [Description](#description)
- [Status](#status)
- [Synopsis](#synopsis)
- [TODO](#todo)
- [Copyright and License](#copyright-and-license)
- [See Also](#see-also)


Description
===========


[Back to TOC](#table-of-contents)

Status
========

Experimental

Synopsis
========


TODO
====

[Back to TOC](#table-of-contents)


Copyright and License
=====================

This module is licensed under the BSD license.

Copyright (C) 2019, by fffonion <fffonion@gmail.com>.

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

[Back to TOC](#table-of-contents)

See Also
========
* [Automatic Certificate Management Environment (ACME)](https://tools.ietf.org/html/rfc8555)
* [haproxytech/haproxy-lua-acme](https://github.com/haproxytech/haproxy-lua-acme) The ACME Lua implementation used in HAProxy.
* [GUI/lua-resty-auto-ssl](https://github.com/GUI/lua-resty-auto-ssl)
* [Let's Encrypt API rate limits](https://letsencrypt.org/docs/rate-limits/)

[Back to TOC](#table-of-contents)
@@ -0,0 +1,11 @@
name = lua-resty-openssl
abstract = FFI-based OpenSSL binding for LuaJIT
author = fffonion
is_original = yes
license = 3bsd
lib_dir = lib
doc_dir = lib
repo_link = https://github.com/fffonion/lua-resty-openssl
main_module = lib/resty/openssl.lua
requires = luajit
exclude_files=*.rock, *.rockspec
@@ -0,0 +1,16 @@

local version_num = require("resty.openssl.version").version_num
if not version_num or version_num < 0x10000000 then
error(string.format("OpenSSL version %x is not supported", version_num or 0))
end

return {
_VERSION = '0.1.0',
version = require("resty.openssl.version"),
pkey = require("resty.openssl.pkey"),
x509 = require("resty.openssl.x509"),
name = require("resty.openssl.x509.name"),
altname = require("resty.openssl.x509.altname"),
csr = require("resty.openssl.x509.csr"),
digest = require("resty.openssl.digest")
}
@@ -0,0 +1,42 @@
local ffi = require "ffi"

local C = ffi.C
local ffi_gc = ffi.gc
local ffi_new = ffi.new

local _M = {}
local mt = {__index = _M}

require "resty.openssl.ossl_typ"

ffi.cdef [[
typedef struct ASN1_VALUE_st ASN1_VALUE;

typedef struct asn1_type_st ASN1_TYPE;

ASN1_OBJECT *ASN1_OBJECT_new(void);
void ASN1_OBJECT_free(ASN1_OBJECT *a);

ASN1_STRING *ASN1_STRING_type_new(int type);
int ASN1_STRING_set(ASN1_STRING *str, const void *data, int len);
]]

local OPENSSL_10 = require("resty.openssl.version").OPENSSL_10

local ASN1_STRING_get0_data
if OPENSSL_10 then
ffi.cdef[[
unsigned char *ASN1_STRING_data(ASN1_STRING *x);
]]
ASN1_STRING_get0_data = C.ASN1_STRING_data
else
ffi.cdef[[
const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *x);
]]
ASN1_STRING_get0_data = C.ASN1_STRING_get0_data
end

return {
ASN1_STRING_get0_data = ASN1_STRING_get0_data
}

@@ -0,0 +1,20 @@
local ffi = require "ffi"

local C = ffi.C
local ffi_gc = ffi.gc
local ffi_new = ffi.new

local _M = {}
local mt = {__index = _M}

require "resty.openssl.ossl_typ"

ffi.cdef [[
typedef struct bio_method_st BIO_METHOD;
long BIO_ctrl(BIO *bp, int cmd, long larg, void *parg);
BIO *BIO_new_mem_buf(const void *buf, int len);
BIO *BIO_new(const BIO_METHOD *type);
int BIO_free(BIO *a);
const BIO_METHOD *BIO_s_mem(void);
int BIO_read(BIO *b, void *data, int dlen);
]]
@@ -0,0 +1,74 @@
local ffi = require "ffi"

local C = ffi.C
local ffi_gc = ffi.gc
local ffi_new = ffi.new
local ffi_str = ffi.string
local floor = math.floor

local _M = {}
local mt = {__index = _M}

require "resty.openssl.ossl_typ"

local BN_ULONG
if ffi.abi('64bit') then
BN_ULONG = 'unsigned long long'
else -- 32bit
BN_ULONG = 'unsigned int'
end

ffi.cdef(
[[
struct bignum_st {
]] .. BN_ULONG ..[[ *d; /* Pointer to an array of 'BN_BITS2' bit
* chunks. */
int top; /* Index of last used d +1. */
/* The next are internal book keeping for bn_expand. */
int dmax; /* Size of the d array. */
int neg; /* one if the number is negative */
int flags;
};
BIGNUM *BN_new(void);
void BN_free(BIGNUM *a);
int BN_add_word(BIGNUM *a, ]] .. BN_ULONG ..[[ w);
int BN_set_word(BIGNUM *a, ]] .. BN_ULONG ..[[ w);
int BN_num_bits(const BIGNUM *a);
int BN_bn2bin(const BIGNUM *a, unsigned char *to);
]]
)

function _M.new(bn)
local _bn
if bn == nil or type(bn) == 'number'then
_bn = C.BN_new()
ffi_gc(_bn, C.BN_free)
if type(bn) == 'number' then
if C.BN_set_word(_bn, bn) ~= 1 then
C.BN_free(bn)
return nil, "BN_set_word() failed"
end
end
elseif type(bn) == 'cdata' then
_bn = bn
else
return nil, "unexpected initializer passed in (got " .. type(bn) .. ")"
end

return setmetatable( { bn = _bn }, mt), nil
end

function _M:toBinary()
local length = (C.BN_num_bits(self.bn)+7)/8
length = floor(length)
local buf = ffi_new('unsigned char[?]', length)
local sz = C.BN_bn2bin(self.bn, buf)
if sz == 0 then
return nil, "BN_bn2bin() failed"
end
buf = ffi_str(buf, length)
return buf, nil
end

return _M
@@ -0,0 +1,61 @@
local ffi = require "ffi"

local C = ffi.C
local ffi_gc = ffi.gc
local ffi_new = ffi.new
local ffi_str = ffi.string

local _M = {}
local mt = {__index = _M}

require "resty.openssl.ossl_typ"
require "resty.openssl.evp"

local version_num = require("resty.openssl.version").version_num

function _M.new(typ)
local ctx
if version_num >= 0x10100000 then
ctx = C.EVP_MD_CTX_new()
ffi_gc(ctx, C.EVP_MD_CTX_free)
else
ctx = C.EVP_MD_CTX_create()
ffi_gc(ctx, C.EVP_MD_CTX_destroy)
end
if ctx == nil then
return nil, "EVP_MD_CTX_new() failed"
end

local typ = C.EVP_get_digestbyname(typ or 'sha1')
if typ == nil then
return nil, "EVP_get_digestbyname() failed"
end

local code = C.EVP_DigestInit_ex(ctx, typ, nil)
if code ~= 1 then
return nil, "EVP_DigestInit_ex() failed: " .. code
end

return setmetatable({ ctx = ctx }, mt), nil
end

function _M:update(...)
for _, s in ipairs({...}) do
C.EVP_DigestUpdate(self.ctx, s, #s)
end
end

local uint_ptr = ffi.typeof("unsigned int[1]")

function _M:final(s)
if s then
C.EVP_DigestUpdate(self.ctx, s, #s)
end
-- # define EVP_MAX_MD_SIZE 64/* longest known is SHA512 */
local buf = ffi_new('unsigned char[?]', 64)
local length = uint_ptr()
C.EVP_DigestFinal_ex(self.ctx, buf, length)
return ffi_str(buf, length[0])
end

return _M

0 comments on commit ec0bb30

Please sign in to comment.
You can’t perform that action at this time.