Skip to content

Commit

Permalink
feat(*) add more modules for OSSL_LIB_CTX support
Browse files Browse the repository at this point in the history
Part of API change in OpenSSL 3.0 #29
  • Loading branch information
fffonion committed Jan 24, 2022
1 parent 4ea2b03 commit dd88ee5
Show file tree
Hide file tree
Showing 17 changed files with 200 additions and 45 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ jobs:
if [ ! -e $OPENSSL_PREFIX/include ]; then sudo make PATH=$PATH install_sw > build.log 2>&1 || (cat build.log && exit 1); fi
if [ -e $OPENSSL_LIB/libcrypto.so.3 ] && [ ! -e $OPENSSL_LIB/ossl-modules/fips.so ]; then mkdir -p $OPENSSL_PREFIX/ssl; sudo make PATH=$PATH install_fips > build.log 2>&1 || (cat build.log && exit 1); fi
if [ ! -e $OPENSSL_PREFIX/lib64 ]; then sudo cp -r $OPENSSL_PREFIX/lib $OPENSSL_PREFIX/lib64; fi
mkdir -p $OPENSSL_PREFIX/certs/ && cp -r /etc/ssl/certs/* $OPENSSL_PREFIX/certs/
mkdir -p $OPENSSL_PREFIX/certs/ && sudo cp -r /etc/ssl/certs/* $OPENSSL_PREFIX/certs/
- name: Build BoringSSL
if: matrix.boringssl != ''
Expand Down Expand Up @@ -185,7 +185,7 @@ jobs:
popd; rm -rf $OPENSSL_INC; cp -r include $OPENSSL_INC
mkdir -p $OPENSSL_LIB; cp -r build/*/*.so $OPENSSL_LIB
fi
mkdir -p $OPENSSL_PREFIX/certs/ && cp -r /etc/ssl/certs/* $OPENSSL_PREFIX/certs/
mkdir -p $OPENSSL_PREFIX/certs/ && sudo cp -r /etc/ssl/certs/* $OPENSSL_PREFIX/certs/
- name: Build LuaJIT
env:
Expand Down
71 changes: 55 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -477,9 +477,17 @@ A module to provide OSSL_LIB_CTX context switches.
See [OSSL_LIB_CTX.3](#https://www.openssl.org/docs/manmaster/man3/OSSL_LIB_CTX.html) for deeper
reading. It can be used to replace `ENGINE` in prior 3.0 world.

The context is currently effective in [cipher](#resty.openssl.cipher),
[pkey](#resty.openssl.pkey), [digest](#resty.openssl.digest), [mac](#resty.openssl.mac),
[kdf](#resty.openssl.kdf) and [provider](#resty.openssl.provider).
The context is currently effective following modules:

- [cipher](#resty.openssl.cipher)
- [digest](#resty.openssl.digest)
- [kdf](#resty.openssl.kdf)
- [mac](#resty.openssl.mac)
- [pkcs12.encode](#pkcs12encode)
- [pkey](#resty.openssl.pkey)
- [provider](#resty.openssl.provider)
- [rand](#resty.openssl.rand)
- [x509](#resty.openssl.x509), [x509.csr](#resty.openssl.x509.csr), [x509.crl](#resty.openssl.x509.crl) and some [x509.store](#resty.openssl.x509.store) functions

This module is only available on OpenSSL 3.0.

Expand Down Expand Up @@ -2120,7 +2128,7 @@ Module to interact with PKCS#12 format.

### pkcs12.encode

**syntax**: *der, err = pkcs12.encode(data, passphrase?)*
**syntax**: *der, err = pkcs12.encode(data, passphrase?, properties?)*

Encode data in `data` to a PKCS#12 text.

Expand All @@ -2132,13 +2140,16 @@ Encode data in `data` to a PKCS#12 text.
| cert | [x509](#restyopensslx509) | Certificate | **required** |
| cacerts | A list of [x509](#restyopensslx509) as Lua table | Additional certificates | `[]` |
| friendly_name | string | The name used for the supplied certificate and key | `""` |
| nid_key | number or string | The [NID] or text to specify algorithm to encrypt key | `"PBE-SHA1-RC2-4"` if compiled with RC2, otherwise `"PBE-SHA1-3DES"` |
| nid_cert | number or string | The [NID] or text to specify algorithm to encrypt cert | `"PBE-SHA1-3DES"` |
| nid_key | number or string | The [NID] or text to specify algorithm to encrypt key | `"PBE-SHA1-RC2-4"` if compiled with RC2, otherwise `"PBE-SHA1-3DES"`; on OpenSSL 3.0 and later `PBES2 with PBKDF2 and AES-256-CBC`. |
| nid_cert | number or string | The [NID] or text to specify algorithm to encrypt cert | `"PBE-SHA1-3DES"`; on OpenSSL 3.0 and later `PBES2 with PBKDF2 and AES-256-CBC` |
| iter | number | Key iterration count | `PKCS12_DEFAULT_ITER` (2048) |
| mac_iter | number | MAC iterration count | 1 |

`passphrase` is the string for encryption. If omitted, an empty string will be used.

Staring from OpenSSL 3.0, this functions accepts an optional `properties` parameter
to explictly select provider to fetch algorithms.

Note in OpenSSL 3.0 `RC2` has been moved to **legacy** provider. In order to encode p12 data with RC2
encryption, you need to [load the legacy provider](#providerload) first.

Expand Down Expand Up @@ -2173,9 +2184,13 @@ Module to interact with random number generator.

### rand.bytes

**syntax**: *str, err = rand.bytes(length)*
**syntax**: *str, err = rand.bytes(length, private?, strength?)*

Generate random bytes with length of `length`. If `private` is set to true, a
private PRNG instance is used so that a compromise of the "public" PRNG instance
will not affect the secrecy of these private values.

Generate random bytes with length of `length`.
The bytes generated will have a security strength of at least `strength` bits.

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

Expand All @@ -2187,13 +2202,16 @@ Module to interact with X.509 certificates.

### x509.new

**syntax**: *crt, err = x509.new(txt?, fmt?)*
**syntax**: *crt, err = x509.new(txt?, fmt?, properties?)*

Creates a `x509` instance. `txt` can be **PEM** or **DER** formatted text;
`fmt` is a choice of `PEM`, `DER` to load specific format, or `*` for auto detect.

When `txt` is omitted, `new()` creates an empty `x509` instance.

Staring from OpenSSL 3.0, this functions accepts an optional `properties` parameter
to explictly select provider to fetch algorithms.

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

### x509.dup
Expand Down Expand Up @@ -2501,13 +2519,16 @@ for an example to generate CSR.

### csr.new

**syntax**: *csr, err = csr.new(txt?, fmt?)*
**syntax**: *csr, err = csr.new(txt?, fmt?, properties?)*

Create an empty `csr` instance. `txt` can be **PEM** or **DER** formatted text;
`fmt` is a choice of `PEM`, `DER` to load specific format, or `*` for auto detect.

When `txt` is omitted, `new()` creates an empty `csr` instance.

Staring from OpenSSL 3.0, this functions accepts an optional `properties` parameter
to explictly select provider to fetch algorithms.

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

### csr.istype
Expand Down Expand Up @@ -2702,13 +2723,16 @@ Module to interact with X509_CRL(certificate revocation list).

### crl.new

**syntax**: *crt, err = crl.new(txt?, fmt?)*
**syntax**: *crt, err = crl.new(txt?, fmt?, properties?)*

Creates a `crl` instance. `txt` can be **PEM** or **DER** formatted text;
`fmt` is a choice of `PEM`, `DER` to load specific format, or `*` for auto detect.

When `txt` is omitted, `new()` creates an empty `crl` instance.

Staring from OpenSSL 3.0, this functions accepts an optional `properties` parameter
to explictly select provider to fetch algorithms.

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

### crl.dup
Expand Down Expand Up @@ -3567,10 +3591,13 @@ Module to interact with X.509 certificate store (X509_STORE).

### store.new

**syntax**: *st, err = store.new()*
**syntax**: *st, err = store.new(properties?)*

Creates a new `store` instance.

Staring from OpenSSL 3.0, this functions accepts an optional `properties` parameter
to explictly select provider to fetch algorithms.

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

### store.istype
Expand All @@ -3583,13 +3610,16 @@ Returns `true` if table is an instance of `store`. Returns `false` otherwise.

### store:use_default

**syntax**: *ok, err = store:use_default()*
**syntax**: *ok, err = store:use_default(properties?)*

Loads certificates into the X509_STORE from the hardcoded default paths.

Note that to load "default" CAs correctly, usually you need to install a CA
certificates bundle. For example, the package in Debian/Ubuntu is called `ca-certificates`.

Staring from OpenSSL 3.0, this functions accepts an optional `properties` parameter
to explictly select provider to fetch algorithms.

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

### store:add
Expand All @@ -3604,25 +3634,31 @@ The argument must be a [resty.openssl.x509](#restyopensslx509) instance or a

### store:load_file

**syntax**: *ok, err = store:load_file(path)*
**syntax**: *ok, err = store:load_file(path, properties?)*

Loads a X.509 certificate on file system into store.

Staring from OpenSSL 3.0, this functions accepts an optional `properties` parameter
to explictly select provider to fetch algorithms.

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

### store:load_directory

**syntax**: *ok, err = store:load_directory(path)*
**syntax**: *ok, err = store:load_directory(path, properties?)*

Loads a directory of X.509 certificates on file system into store. The certificates in the directory
must be in hashed form, as documented in
[X509_LOOKUP_hash_dir(3)](https://www.openssl.org/docs/manmaster/man3/X509_LOOKUP_hash_dir.html).

Staring from OpenSSL 3.0, this functions accepts an optional `properties` parameter
to explictly select provider to fetch algorithms.

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

### store:verify

**syntax**: *chain, err = store:verify(x509, chain?, return_chain?)*
**syntax**: *chain, err = store:verify(x509, chain?, return_chain?, properties?)*

Verifies a X.509 object with the store. The first argument must be
[resty.openssl.x509](#restyopensslx509) instance. Optionally accept a validation chain as second
Expand All @@ -3632,6 +3668,9 @@ If verification succeed, and `return_chain` is set to true, returns the proof of
[resty.openssl.x509.chain](#restyopensslx509chain); otherwise
returns `true` only. If verification failed, returns `nil` and error explaining the reason.

Staring from OpenSSL 3.0, this functions accepts an optional `properties` parameter
to explictly select provider to fetch algorithms.

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

## resty.openssl.x509.revoked
Expand Down
3 changes: 1 addition & 2 deletions lib/resty/openssl/ctx.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ local ffi = require "ffi"
local C = ffi.C
local ffi_gc = ffi.gc

require "resty.openssl.include.ossl_typ"
local format_error = require("resty.openssl.err").format_error
local OPENSSL_30 = require("resty.openssl.version").OPENSSL_30

ffi.cdef [[
typedef struct ossl_lib_ctx_st OSSL_LIB_CTX;

OSSL_LIB_CTX *OSSL_LIB_CTX_new(void);
int OSSL_LIB_CTX_load_config(OSSL_LIB_CTX *ctx, const char *config_file);
void OSSL_LIB_CTX_free(OSSL_LIB_CTX *ctx);
Expand Down
13 changes: 10 additions & 3 deletions lib/resty/openssl/include/asn1.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ local ffi = require "ffi"
local C = ffi.C

require "resty.openssl.include.ossl_typ"
local OPENSSL_30 = require("resty.openssl.version").OPENSSL_30

ffi.cdef [[
typedef struct ASN1_VALUE_st ASN1_VALUE;
Expand All @@ -27,7 +28,7 @@ ffi.cdef [[
int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v);
]]

local function declare_asn1_functions(typ)
local function declare_asn1_functions(typ, has_ex)
local t = {}
for i=1, 7 do
t[i] = typ
Expand All @@ -37,8 +38,13 @@ local function declare_asn1_functions(typ)
%s *%s_new(void);
void %s_free(%s *a);
%s *%s_dup(%s *a);
]], unpack(t))
)
]], unpack(t)))

if OPENSSL_30 and has_ex then
ffi.cdef(string.format([[
%s *%s_new_ex(OSSL_LIB_CTX *libctx, const char *propq);
]], typ, typ))
end
end

declare_asn1_functions("ASN1_INTEGER")
Expand Down Expand Up @@ -82,4 +88,5 @@ end
return {
ASN1_STRING_get0_data = ASN1_STRING_get0_data,
declare_asn1_functions = declare_asn1_functions,
has_new_ex = true,
}
1 change: 1 addition & 0 deletions lib/resty/openssl/include/ossl_typ.lua
Original file line number Diff line number Diff line change
Expand Up @@ -65,5 +65,6 @@ ffi.cdef(
typedef struct ssl_ctx_st SSL_CTX;
typedef struct evp_kdf_st EVP_KDF;
typedef struct evp_kdf_ctx_st EVP_KDF_CTX;
typedef struct ossl_lib_ctx_st OSSL_LIB_CTX;
]])

13 changes: 13 additions & 0 deletions lib/resty/openssl/include/pkcs12.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ local ffi = require "ffi"
require "resty.openssl.include.ossl_typ"
require "resty.openssl.include.stack"

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

ffi.cdef [[
// hack by changing char* to const char* here
PKCS12 *PKCS12_create(const char *pass, const char *name, EVP_PKEY *pkey, X509 *cert,
Expand All @@ -16,3 +18,14 @@ ffi.cdef [[
int i2d_PKCS12_bio(BIO *bp, PKCS12 *a);
PKCS12 *d2i_PKCS12_bio(BIO *bp, PKCS12 **a);
]]

if OPENSSL_30 then
ffi.cdef [[
PKCS12 *PKCS12_create_ex(const char *pass, const char *name, EVP_PKEY *pkey,
X509 *cert,
OPENSSL_STACK *ca, // STACK_OF(X509)
int nid_key, int nid_cert,
int iter, int mac_iter, int keytype,
OSSL_LIB_CTX *ctx, const char *propq);
]]
end
13 changes: 13 additions & 0 deletions lib/resty/openssl/include/rand.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
local ffi = require "ffi"

require "resty.openssl.include.ossl_typ"
local OPENSSL_30 = require("resty.openssl.version").OPENSSL_30

ffi.cdef [[
int RAND_bytes(unsigned char *buf, int num);
int RAND_priv_bytes(unsigned char *buf, int num);
]]

if OPENSSL_30 then
ffi.cdef [[
int RAND_bytes_ex(OSSL_LIB_CTX *ctx, unsigned char *buf, size_t num,
unsigned int strength);
int RAND_priv_bytes_ex(OSSL_LIB_CTX *ctx, unsigned char *buf, size_t num,
unsigned int strength);
]]
end
2 changes: 1 addition & 1 deletion lib/resty/openssl/include/x509/crl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ local OPENSSL_10 = require("resty.openssl.version").OPENSSL_10
local OPENSSL_11_OR_LATER = require("resty.openssl.version").OPENSSL_11_OR_LATER
local BORINGSSL_110 = require("resty.openssl.version").BORINGSSL_110

asn1_macro.declare_asn1_functions("X509_CRL")
asn1_macro.declare_asn1_functions("X509_CRL", asn1_macro.has_new_ex)

ffi.cdef [[
X509_NAME *X509_CRL_get_issuer(const X509_CRL *crl);
Expand Down
10 changes: 9 additions & 1 deletion lib/resty/openssl/include/x509/csr.lua
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ local asn1_macro = require "resty.openssl.include.asn1"

local OPENSSL_10 = require("resty.openssl.version").OPENSSL_10
local OPENSSL_11_OR_LATER = require("resty.openssl.version").OPENSSL_11_OR_LATER
local OPENSSL_30 = require("resty.openssl.version").OPENSSL_30
local BORINGSSL_110 = require("resty.openssl.version").BORINGSSL_110

asn1_macro.declare_asn1_functions("X509_REQ")
asn1_macro.declare_asn1_functions("X509_REQ", asn1_macro.has_new_ex)

ffi.cdef [[
int X509_REQ_set_subject_name(X509_REQ *req, X509_NAME *name);
Expand Down Expand Up @@ -78,3 +79,10 @@ if OPENSSL_10 or BORINGSSL_110 then
} X509_REQ;
]]
end

if OPENSSL_30 then
ffi.cdef [[
int X509_REQ_verify_ex(X509_REQ *a, EVP_PKEY *pkey, OSSL_LIB_CTX *libctx,
const char *propq);
]]
end
2 changes: 1 addition & 1 deletion lib/resty/openssl/include/x509/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ local OPENSSL_10 = require("resty.openssl.version").OPENSSL_10
local OPENSSL_11_OR_LATER = require("resty.openssl.version").OPENSSL_11_OR_LATER
local BORINGSSL_110 = require("resty.openssl.version").BORINGSSL_110

asn1_macro.declare_asn1_functions("X509")
asn1_macro.declare_asn1_functions("X509", asn1_macro.has_new_ex)

ffi.cdef [[
int i2d_X509_bio(BIO *bp, X509 *x509);
Expand Down
22 changes: 22 additions & 0 deletions lib/resty/openssl/include/x509_vfy.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ require "resty.openssl.include.ossl_typ"
require "resty.openssl.include.stack"
local OPENSSL_10 = require("resty.openssl.version").OPENSSL_10
local OPENSSL_11_OR_LATER = require("resty.openssl.version").OPENSSL_11_OR_LATER
local OPENSSL_30 = require("resty.openssl.version").OPENSSL_30
local BORINGSSL_110 = require("resty.openssl.version").BORINGSSL_110

ffi.cdef [[
Expand Down Expand Up @@ -49,5 +50,26 @@ elseif OPENSSL_11_OR_LATER then
_M.X509_STORE_CTX_get0_chain = C.X509_STORE_CTX_get0_chain
end

if OPENSSL_30 then
ffi.cdef [[
X509_STORE_CTX *X509_STORE_CTX_new_ex(OSSL_LIB_CTX *libctx, const char *propq);

int X509_STORE_set_default_paths_ex(X509_STORE *ctx, OSSL_LIB_CTX *libctx,
const char *propq);
/* int X509_STORE_load_file_ex(X509_STORE *ctx, const char *file,
OSSL_LIB_CTX *libctx, const char *propq);
int X509_STORE_load_store_ex(X509_STORE *ctx, const char *uri,
OSSL_LIB_CTX *libctx, const char *propq); */
int X509_STORE_load_locations_ex(X509_STORE *ctx, const char *file,
const char *dir, OSSL_LIB_CTX *libctx,
const char *propq);
]]
_M.X509_STORE_set_default_paths = function(...) return C.X509_STORE_set_default_paths_ex(...) end
_M.X509_STORE_load_locations = function(...) return C.X509_STORE_load_locations_ex(...) end
else
_M.X509_STORE_set_default_paths = function(s) return C.X509_STORE_set_default_paths(s) end
_M.X509_STORE_load_locations = function(s, file, dir) return C.X509_STORE_load_locations(s, file, dir) end
end

return _M

Loading

0 comments on commit dd88ee5

Please sign in to comment.