Skip to content

Commit fad844f

Browse files
committed
feat(openssl) lua-resty-hmac compat
1 parent 79fbe68 commit fad844f

File tree

4 files changed

+104
-49
lines changed

4 files changed

+104
-49
lines changed

.travis.yml

+2
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ install:
4949
- git clone https://github.com/openresty/no-pool-nginx.git ./no-pool-nginx
5050
- git clone https://github.com/openresty/lua-resty-core.git ../lua-resty-core
5151
- git clone https://github.com/openresty/lua-resty-lrucache.git ../lua-resty-lrucache
52+
- git clone https://github.com/jkeys089/lua-resty-hmac ../lua-resty-hmac
53+
- git clone https://github.com/openresty/lua-resty-string ../lua-resty-string
5254
# openssl
5355
# openssl 1.0.2 config doesn't work correctly on a cached directory
5456
- wget https://www.openssl.org/source/openssl-$OPENSSL_VER.tar.gz -O - | tar zxf -

README.md

+39-48
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ Table of Contents
1212
- [Status](#status)
1313
- [Synopsis](#synopsis)
1414
* [resty.openssl](#restyopenssl)
15-
+ [openssl.luaossl_compat](#opensslluaossl-compat)
15+
+ [openssl.luaossl_compat](#opensslluaossl_compat)
16+
+ [openssl.resty_hmac_compat](#opensslresty_hmac_compat)
1617
* [resty.openssl.version](#restyopensslversion)
1718
+ [version_num](#version_num)
1819
+ [version_text](#version_text)
@@ -230,6 +231,15 @@ Note that not all `luaossl` API has been implemented, please check readme for so
230231

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

234+
### openssl.resty_hmac_compat
235+
236+
**syntax**: *openssl.resty_hmac_compat()*
237+
238+
Call this function before `require("resty.hmac")` to allow these two libraries play nice with
239+
each other. This function is not available with OpenSSL 1.0.
240+
241+
[Back to TOC](#table-of-contents)
242+
233243
## resty.openssl.version
234244

235245
A module to provide version info.
@@ -302,46 +312,34 @@ Module to interact with private keys and public keys (EVP_PKEY).
302312

303313
**syntax**: *pk, err = pkey.new(config)*
304314

305-
**syntax**: *pk, err = pkey.new(string, opts?)*
315+
**syntax**: *pk, err = pkey.new(string, format?)*
306316

307317
**syntax**: *pk, err = pkey.new()*
308318

309319
Creates a new pkey instance. The first argument can be:
310320

311-
1. A `config` table to create a new PKEY pair. Which defaults to:
321+
1. A table which defaults to:
312322

313323
```lua
314-
pkey.new({
315-
type = 'RSA',
316-
bits = 2048,
317-
exp = 65537
318-
})
324+
{
325+
type = 'RSA',
326+
bits = 2048,
327+
exp = 65537
328+
}
319329
```
320330

321331
to create EC private key:
322332

323333
```lua
324-
pkey.new({
325-
type = 'EC',
326-
curve = 'primve196v1',
327-
})
328-
```
329-
330-
2. A `string` of private or public key in PEM or DER format; optionally accpet a table `opts`
331-
to explictly load `format` and key `type`. When loading a key in PEM format,
332-
`passphrase` or `passphrase_cb` may be provided to decrypt the key.
333-
334-
```lua
335-
pkey.new(pem_or_der_text, {
336-
format = "*", -- choice of "PEM", "DER" or "*" for auto detect
337-
type = "*", -- choice of "p"r for privatekey, "pu" for public key and "*" for auto detect
338-
passphrase = "secret password", -- the PEM encryption passphrase
339-
passphrase_cb = function()
340-
return "secret password"
341-
end, -- the PEM encryption passphrase callback function
334+
{
335+
type = 'EC',
336+
curve = 'primve196v1',
342337
}
343-
344338
```
339+
340+
2. A string of private or public key in PEM or DER format; optionally tells the library
341+
to explictly decode the key using `format`, which can be a choice of `PER`, `DER` or `*`
342+
for auto detect.
345343
3. `nil` to create a 2048 bits RSA key.
346344
4. A `EVP_PKEY*` pointer, to return a wrapped `pkey` instance. Normally user won't use this
347345
approach. User shouldn't free the pointer on their own, since the pointer is not copied.
@@ -365,7 +363,7 @@ parameter of RSA key is supported. Each value of the returned table is a
365363
[resty.openssl.bn](#restyopensslbn) instance.
366364

367365
```lua
368-
local pk, err = require("resty.openssl.pkey").new()
366+
local pk, err = require("resty.openssl").pkey.new()
369367
local parameters, err = pk:get_parameters()
370368
local e = parameters.e
371369
ngx.say(ngx.encode_base64(e:to_binary()))
@@ -383,8 +381,8 @@ instance. The `digest` parameter must be a [resty.openssl.digest](#restyopenssld
383381
instance. Returns the signed raw binary and error if any.
384382

385383
```lua
386-
local pk, err = require("resty.openssl.pkey").new()
387-
local digest, err = require("resty.openssl.digest").new("SHA256")
384+
local pk, err = require("resty.openssl").pkey.new()
385+
local digest, err = require("resty.openssl").digest.new("SHA256")
388386
digest:update("dog")
389387
local signature, err = pk:sign(digest)
390388
ngx.say(ngx.encode_base64(signature))
@@ -913,7 +911,7 @@ ngx.say(not_before)
913911
err = x509:set_basic_constraints_critical(true)
914912
```
915913

916-
If type is a table, setter requires a table with case-insensitive keys to set;
914+
If type is a table, setter requires a table with case-insentive keys to set;
917915
getter returns the value of the given case-insensitive key or a table of all keys if no key provided.
918916

919917
```lua
@@ -1629,7 +1627,7 @@ Returns the name of extension as ASN.1 Object. User can further use helper funct
16291627

16301628
### extension:text
16311629

1632-
**syntax**: *txt, err = extension:text()*
1630+
**syntax**: *txt, err = extension:text(table)*
16331631

16341632
Returns the text representation of extension
16351633

@@ -1643,14 +1641,6 @@ ngx.say(extension:text())
16431641

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

1646-
### extension:tostring
1647-
1648-
**syntax**: *txt, err = extension:tostring()*
1649-
1650-
Same as [extension:text](#extensiontext).
1651-
1652-
[Back to TOC](#table-of-contents)
1653-
16541644
## resty.openssl.x509.extension.dist_points
16551645

16561646
Module to interact with CRL Distribution Points(DIST_POINT stack).
@@ -1848,11 +1838,9 @@ certificates bundle. For example, the package in Debian/Ubuntu is called `ca-cer
18481838

18491839
### store:add
18501840

1851-
**syntax**: *ok, err = store:add(x509_or_crl)*
1841+
**syntax**: *ok, err = store:add(x509)*
18521842

1853-
Adds a X.509 or a CRL object into store.
1854-
The argument must be a [resty.openssl.x509](#restyopensslx509) instance or a
1855-
[resty.openssl.x509.store](#restyopensslx509store) instance.
1843+
Adds a X.509 object into store. The argument must be a [resty.openssl.x509](#restyopensslx509) instance.
18561844

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

@@ -1882,9 +1870,8 @@ Verifies a X.509 object with the store. The first argument must be
18821870
[resty.openssl.x509](#restyopensslx509) instance. Optionally accept a validation chain as second
18831871
argument, which must be a [resty.openssl.x509.chain](#restyopensslx509chain) instance.
18841872

1885-
If verification succeed, and `return_chain` is set to true, returns the proof of validation as a
1886-
[resty.openssl.x509.chain](#restyopensslx509chain); otherwise
1887-
returns `true` only. If verification failed, returns `nil` and error explaining the reason.
1873+
If verification succeed, and `return_chain` is set to true, returns the proof of validation; otherwise
1874+
returns `true`. If verification failed, returns `nil` and error explaining the reason.
18881875

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

@@ -1998,6 +1985,10 @@ same.
19981985
If you plan to use this library on an untested version of OpenSSL (like custom builds or pre releases),
19991986
[this](https://abi-laboratory.pro/index.php?view=timeline&l=openssl) can be a good source to consult.
20001987

1988+
TODO
1989+
====
1990+
1991+
- add tests for x509 getters/setters
20011992

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

@@ -2007,7 +1998,7 @@ Copyright and License
20071998

20081999
This module is licensed under the BSD license.
20092000

2010-
Copyright (C) 2019-2020, by fffonion <[email protected]>.
2001+
Copyright (C) 2019, by fffonion <[email protected]>.
20112002

20122003
All rights reserved.
20132004

lib/resty/openssl.lua

+27
Original file line numberDiff line numberDiff line change
@@ -117,4 +117,31 @@ end
117117
-- we made a typo sometime, this is going to be removed in next major release
118118
_M.luaossl_compact = _M.luaossl_compat
119119

120+
local resty_hmac_compat_patched = false
121+
function _M.resty_hmac_compat()
122+
if resty_hmac_compat_patched then
123+
return
124+
end
125+
if _M.version.OPENSSL_10 then
126+
error("use resty_hmac_compat in OpenSSL 1.0 is not supported")
127+
end
128+
129+
require("resty.openssl.include.evp")
130+
require("ffi").cdef [[
131+
// originally named evp_cipher_ctx_st in evp.lua
132+
struct evp_md_ctx_st {
133+
const EVP_MD *digest;
134+
ENGINE *engine; /* functional reference if 'digest' is
135+
* ENGINE-provided */
136+
unsigned long flags;
137+
void *md_data;
138+
/* Public key context for sign/verify */
139+
EVP_PKEY_CTX *pctx;
140+
/* Update function: usually copied from EVP_MD */
141+
int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count);
142+
}/* EVP_MD_CTX */ ;
143+
]]
144+
resty_hmac_compat_patched = true
145+
end
146+
120147
return _M

t/openssl.t

+36-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ my $pwd = cwd();
99
my $use_luacov = $ENV{'TEST_NGINX_USE_LUACOV'} // '';
1010

1111
our $HttpConfig = qq{
12-
lua_package_path "$pwd/lib/?.lua;$pwd/lib/?/init.lua;;";
12+
lua_package_path "$pwd/lib/?.lua;$pwd/lib/?/init.lua;$pwd/../lua-resty-hmac/lib/?.lua;$pwd/../lua-resty-string/lib/?.lua;;";
1313
init_by_lua_block {
1414
if "1" == "$use_luacov" then
1515
require 'luacov.tick'
@@ -57,4 +57,39 @@ __DATA__
5757
false
5858
.+pkey.new.+
5959
--- no_error_log
60+
[error]
61+
62+
=== TEST 3: lua-resty-hmac compat
63+
--- http_config eval: $::HttpConfig
64+
--- config
65+
location =/t {
66+
content_by_lua_block {
67+
local openssl = require("resty.openssl")
68+
if openssl.version.OPENSSL_10 then
69+
-- noop
70+
local pok, perr = pcall(openssl.resty_hmac_compat)
71+
ngx.say(pok)
72+
ngx.say("-size of C type is unknown or too large-")
73+
ngx.say(true)
74+
ngx.say(ngx.null)
75+
else
76+
require("resty.openssl.hmac")
77+
local pok, perr = pcall(require, "resty.hmac")
78+
ngx.say(pok)
79+
ngx.say(perr)
80+
openssl.resty_hmac_compat()
81+
local pok, perr = pcall(require, "resty.hmac")
82+
ngx.say(pok)
83+
ngx.say(perr)
84+
end
85+
}
86+
}
87+
--- request
88+
GET /t
89+
--- response_body_like
90+
false
91+
.+size of C type is unknown or too large.+
92+
true
93+
null
94+
--- no_error_log
6095
[error]

0 commit comments

Comments
 (0)