From 1bd0dcbd7c62fb4acdfeda90307471440e143f8f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 28 Dec 2023 08:55:53 +0000 Subject: [PATCH 01/11] deps/gha: bump ruby/setup-ruby from 1.163.0 to 1.165.0 Bumps [ruby/setup-ruby](https://github.com/ruby/setup-ruby) from 1.163.0 to 1.165.0. - [Release notes](https://github.com/ruby/setup-ruby/releases) - [Commits](https://github.com/ruby/setup-ruby/compare/b256bd96bb4867e7d23e92e087d9bb697270b725...961f85197f92e4842e3cb92a4f97bd8e010cdbaf) --- updated-dependencies: - dependency-name: ruby/setup-ruby dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/push-packagecloud.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/push-packagecloud.yml b/.github/workflows/push-packagecloud.yml index 9e939c79c..28d40e442 100644 --- a/.github/workflows/push-packagecloud.yml +++ b/.github/workflows/push-packagecloud.yml @@ -42,7 +42,7 @@ jobs: - name: Check out repository code uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Install ruby - uses: ruby/setup-ruby@b256bd96bb4867e7d23e92e087d9bb697270b725 # v1.163.0 + uses: ruby/setup-ruby@961f85197f92e4842e3cb92a4f97bd8e010cdbaf # v1.165.0 with: ruby-version: "3.0" - name: Install packagecloud From c7e690d9491cc8c055300d5eed18d6e372e9e8a9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 Dec 2023 08:44:40 +0000 Subject: [PATCH 02/11] deps/gha: bump ruby/setup-ruby from 1.165.0 to 1.165.1 Bumps [ruby/setup-ruby](https://github.com/ruby/setup-ruby) from 1.165.0 to 1.165.1. - [Release notes](https://github.com/ruby/setup-ruby/releases) - [Commits](https://github.com/ruby/setup-ruby/compare/961f85197f92e4842e3cb92a4f97bd8e010cdbaf...360dc864d5da99d54fcb8e9148c14a84b90d3e88) --- updated-dependencies: - dependency-name: ruby/setup-ruby dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/push-packagecloud.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/push-packagecloud.yml b/.github/workflows/push-packagecloud.yml index 28d40e442..5bcbb259d 100644 --- a/.github/workflows/push-packagecloud.yml +++ b/.github/workflows/push-packagecloud.yml @@ -42,7 +42,7 @@ jobs: - name: Check out repository code uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Install ruby - uses: ruby/setup-ruby@961f85197f92e4842e3cb92a4f97bd8e010cdbaf # v1.165.0 + uses: ruby/setup-ruby@360dc864d5da99d54fcb8e9148c14a84b90d3e88 # v1.165.1 with: ruby-version: "3.0" - name: Install packagecloud From 22c6e1c6d679b9d72d021c34f591676889682f42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophile=20Diot?= Date: Fri, 29 Dec 2023 12:35:22 +0000 Subject: [PATCH 03/11] Update python deps --- docs/requirements.txt | 6 +- src/common/db/requirements.in | 2 +- src/common/db/requirements.txt | 100 +++++++++++----------- tests/core/blacklist/api/requirements.in | 2 +- tests/core/blacklist/api/requirements.txt | 20 ++--- tests/core/bunkernet/api/requirements.in | 2 +- tests/core/bunkernet/api/requirements.txt | 20 ++--- tests/core/db/requirements.in | 2 +- tests/core/db/requirements.txt | 100 +++++++++++----------- tests/core/greylist/api/requirements.in | 2 +- tests/core/greylist/api/requirements.txt | 20 ++--- tests/core/redis/requirements.in | 2 +- tests/core/redis/requirements.txt | 20 ++--- tests/core/reversescan/requirements.in | 2 +- tests/core/reversescan/requirements.txt | 20 ++--- tests/core/whitelist/api/requirements.in | 2 +- tests/core/whitelist/api/requirements.txt | 20 ++--- 17 files changed, 171 insertions(+), 171 deletions(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index f6e0b4cc6..fa0c63b66 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -425,9 +425,9 @@ pygments==2.17.2 \ --hash=sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c \ --hash=sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367 # via mkdocs-material -pymdown-extensions==10.5 \ - --hash=sha256:1b60f1e462adbec5a1ed79dac91f666c9c0d241fa294de1989f29d20096cfd0b \ - --hash=sha256:1f0ca8bb5beff091315f793ee17683bc1390731f6ac4c5eb01e27464b80fe879 +pymdown-extensions==10.6 \ + --hash=sha256:561eb3a5f3c3c2512952a4d6f5b311aa124b7147bd54a3ea0f36ce030c7e3dd9 \ + --hash=sha256:e4531379e0d74b329ff264217ef5b8b1a37bed3afe36f98001b74ecff52215c0 # via mkdocs-material pyparsing==3.1.1 \ --hash=sha256:32c7c0b711493c72ff18a981d24f28aaf9c1fb7ed5e9667c9e84e3db623bdbfb \ diff --git a/src/common/db/requirements.in b/src/common/db/requirements.in index c4e5787e0..c5007d3fb 100644 --- a/src/common/db/requirements.in +++ b/src/common/db/requirements.in @@ -1,4 +1,4 @@ cryptography==41.0.7 psycopg2-binary==2.9.9 PyMySQL==1.1.0 -sqlalchemy==2.0.23 +sqlalchemy==2.0.24 diff --git a/src/common/db/requirements.txt b/src/common/db/requirements.txt index 9fc2e96b2..74ce73216 100644 --- a/src/common/db/requirements.txt +++ b/src/common/db/requirements.txt @@ -225,56 +225,56 @@ pymysql==1.1.0 \ --hash=sha256:4f13a7df8bf36a51e81dd9f3605fede45a4878fe02f9236349fd82a3f0612f96 \ --hash=sha256:8969ec6d763c856f7073c4c64662882675702efcb114b4bcbb955aea3a069fa7 # via -r requirements.in -sqlalchemy==2.0.23 \ - --hash=sha256:0666031df46b9badba9bed00092a1ffa3aa063a5e68fa244acd9f08070e936d3 \ - --hash=sha256:0a8c6aa506893e25a04233bc721c6b6cf844bafd7250535abb56cb6cc1368884 \ - --hash=sha256:0e680527245895aba86afbd5bef6c316831c02aa988d1aad83c47ffe92655e74 \ - --hash=sha256:14aebfe28b99f24f8a4c1346c48bc3d63705b1f919a24c27471136d2f219f02d \ - --hash=sha256:1e018aba8363adb0599e745af245306cb8c46b9ad0a6fc0a86745b6ff7d940fc \ - --hash=sha256:227135ef1e48165f37590b8bfc44ed7ff4c074bf04dc8d6f8e7f1c14a94aa6ca \ - --hash=sha256:31952bbc527d633b9479f5f81e8b9dfada00b91d6baba021a869095f1a97006d \ - --hash=sha256:3e983fa42164577d073778d06d2cc5d020322425a509a08119bdcee70ad856bf \ - --hash=sha256:42d0b0290a8fb0165ea2c2781ae66e95cca6e27a2fbe1016ff8db3112ac1e846 \ - --hash=sha256:42ede90148b73fe4ab4a089f3126b2cfae8cfefc955c8174d697bb46210c8306 \ - --hash=sha256:4895a63e2c271ffc7a81ea424b94060f7b3b03b4ea0cd58ab5bb676ed02f4221 \ - --hash=sha256:4af79c06825e2836de21439cb2a6ce22b2ca129bad74f359bddd173f39582bf5 \ - --hash=sha256:5f94aeb99f43729960638e7468d4688f6efccb837a858b34574e01143cf11f89 \ - --hash=sha256:616fe7bcff0a05098f64b4478b78ec2dfa03225c23734d83d6c169eb41a93e55 \ - --hash=sha256:62d9e964870ea5ade4bc870ac4004c456efe75fb50404c03c5fd61f8bc669a72 \ - --hash=sha256:638c2c0b6b4661a4fd264f6fb804eccd392745c5887f9317feb64bb7cb03b3ea \ - --hash=sha256:63bfc3acc970776036f6d1d0e65faa7473be9f3135d37a463c5eba5efcdb24c8 \ - --hash=sha256:6463aa765cf02b9247e38b35853923edbf2f6fd1963df88706bc1d02410a5577 \ - --hash=sha256:64ac935a90bc479fee77f9463f298943b0e60005fe5de2aa654d9cdef46c54df \ - --hash=sha256:683ef58ca8eea4747737a1c35c11372ffeb84578d3aab8f3e10b1d13d66f2bc4 \ - --hash=sha256:75eefe09e98043cff2fb8af9796e20747ae870c903dc61d41b0c2e55128f958d \ - --hash=sha256:787af80107fb691934a01889ca8f82a44adedbf5ef3d6ad7d0f0b9ac557e0c34 \ - --hash=sha256:7c424983ab447dab126c39d3ce3be5bee95700783204a72549c3dceffe0fc8f4 \ - --hash=sha256:7e0dc9031baa46ad0dd5a269cb7a92a73284d1309228be1d5935dac8fb3cae24 \ - --hash=sha256:87a3d6b53c39cd173990de2f5f4b83431d534a74f0e2f88bd16eabb5667e65c6 \ - --hash=sha256:89a01238fcb9a8af118eaad3ffcc5dedaacbd429dc6fdc43fe430d3a941ff965 \ - --hash=sha256:9585b646ffb048c0250acc7dad92536591ffe35dba624bb8fd9b471e25212a35 \ - --hash=sha256:964971b52daab357d2c0875825e36584d58f536e920f2968df8d581054eada4b \ - --hash=sha256:967c0b71156f793e6662dd839da54f884631755275ed71f1539c95bbada9aaab \ - --hash=sha256:9ca922f305d67605668e93991aaf2c12239c78207bca3b891cd51a4515c72e22 \ - --hash=sha256:a86cb7063e2c9fb8e774f77fbf8475516d270a3e989da55fa05d08089d77f8c4 \ - --hash=sha256:aeb397de65a0a62f14c257f36a726945a7f7bb60253462e8602d9b97b5cbe204 \ - --hash=sha256:b41f5d65b54cdf4934ecede2f41b9c60c9f785620416e8e6c48349ab18643855 \ - --hash=sha256:bd45a5b6c68357578263d74daab6ff9439517f87da63442d244f9f23df56138d \ - --hash=sha256:c14eba45983d2f48f7546bb32b47937ee2cafae353646295f0e99f35b14286ab \ - --hash=sha256:c1bda93cbbe4aa2aa0aa8655c5aeda505cd219ff3e8da91d1d329e143e4aff69 \ - --hash=sha256:c4722f3bc3c1c2fcc3702dbe0016ba31148dd6efcd2a2fd33c1b4897c6a19693 \ - --hash=sha256:c80c38bd2ea35b97cbf7c21aeb129dcbebbf344ee01a7141016ab7b851464f8e \ - --hash=sha256:cabafc7837b6cec61c0e1e5c6d14ef250b675fa9c3060ed8a7e38653bd732ff8 \ - --hash=sha256:cc1d21576f958c42d9aec68eba5c1a7d715e5fc07825a629015fe8e3b0657fb0 \ - --hash=sha256:d0f7fb0c7527c41fa6fcae2be537ac137f636a41b4c5a4c58914541e2f436b45 \ - --hash=sha256:d4041ad05b35f1f4da481f6b811b4af2f29e83af253bf37c3c4582b2c68934ab \ - --hash=sha256:d5578e6863eeb998980c212a39106ea139bdc0b3f73291b96e27c929c90cd8e1 \ - --hash=sha256:e3b5036aa326dc2df50cba3c958e29b291a80f604b1afa4c8ce73e78e1c9f01d \ - --hash=sha256:e599a51acf3cc4d31d1a0cf248d8f8d863b6386d2b6782c5074427ebb7803bda \ - --hash=sha256:f3420d00d2cb42432c1d0e44540ae83185ccbbc67a6054dcc8ab5387add6620b \ - --hash=sha256:f48ed89dd11c3c586f45e9eec1e437b355b3b6f6884ea4a4c3111a3358fd0c18 \ - --hash=sha256:f508ba8f89e0a5ecdfd3761f82dda2a3d7b678a626967608f4273e0dba8f07ac \ - --hash=sha256:fd54601ef9cc455a0c61e5245f690c8a3ad67ddb03d3b91c361d076def0b4c60 +sqlalchemy==2.0.24 \ + --hash=sha256:00d76fe5d7cdb5d84d625ce002ce29fefba0bfd98e212ae66793fed30af73931 \ + --hash=sha256:07cc423892f2ceda9ae1daa28c0355757f362ecc7505b1ab1a3d5d8dc1c44ac6 \ + --hash=sha256:0bb7cedcddffca98c40bb0becd3423e293d1fef442b869da40843d751785beb3 \ + --hash=sha256:1ca7903d5e7db791a355b579c690684fac6304478b68efdc7f2ebdcfe770d8d7 \ + --hash=sha256:1d9b3fd5eca3c0b137a5e0e468e24ca544ed8ca4783e0e55341b7ed2807518ee \ + --hash=sha256:2587e108463cc2e5b45a896b2e7cc8659a517038026922a758bde009271aed11 \ + --hash=sha256:29e51f848f843bbd75d74ae64ab1ab06302cb1dccd4549d1f5afe6b4a946edb2 \ + --hash=sha256:2a479aa1ab199178ff1956b09ca8a0693e70f9c762875d69292d37049ffd0d8f \ + --hash=sha256:37e89d965b52e8b20571b5d44f26e2124b26ab63758bf1b7598a0e38fb2c4005 \ + --hash=sha256:38732884eabc64982a09a846bacf085596ff2371e4e41d20c0734f7e50525d01 \ + --hash=sha256:396f05c552f7fa30a129497c41bef5b4d1423f9af8fe4df0c3dcd38f3e3b9a14 \ + --hash=sha256:4a1d4856861ba9e73bac05030cec5852eabfa9ef4af8e56c19d92de80d46fc34 \ + --hash=sha256:56a0e90a959e18ac5f18c80d0cad9e90cb09322764f536e8a637426afb1cae2f \ + --hash=sha256:57ef6f2cb8b09a042d0dbeaa46a30f2df5dd1e1eb889ba258b0d5d7d6011b81c \ + --hash=sha256:5f801d85ba4753d4ed97181d003e5d3fa330ac7c4587d131f61d7f968f416862 \ + --hash=sha256:6db686a1d9f183c639f7e06a2656af25d4ed438eda581de135d15569f16ace33 \ + --hash=sha256:6db97656fd3fe3f7e5b077f12fa6adb5feb6e0b567a3e99f47ecf5f7ea0a09e3 \ + --hash=sha256:6f5e75de91c754365c098ac08c13fdb267577ce954fa239dd49228b573ca88d7 \ + --hash=sha256:7a6209e689d0ff206c40032b6418e3cfcfc5af044b3f66e381d7f1ae301544b4 \ + --hash=sha256:7ae5d44517fe81079ce75cf10f96978284a6db2642c5932a69c82dbae09f009a \ + --hash=sha256:83fa6df0e035689df89ff77a46bf8738696785d3156c2c61494acdcddc75c69d \ + --hash=sha256:8f358f5cfce04417b6ff738748ca4806fe3d3ae8040fb4e6a0c9a6973ccf9b6e \ + --hash=sha256:9036ebfd934813990c5b9f71f297e77ed4963720db7d7ceec5a3fdb7cd2ef6ce \ + --hash=sha256:95bae3d38f8808d79072da25d5e5a6095f36fe1f9d6c614dd72c59ca8397c7c0 \ + --hash=sha256:9aaaaa846b10dfbe1bda71079d0e31a7e2cebedda9409fa7dba3dfed1ae803e8 \ + --hash=sha256:9b8d0e8578e7f853f45f4512b5c920f6a546cd4bed44137460b2a56534644205 \ + --hash=sha256:9bafaa05b19dc07fa191c1966c5e852af516840b0d7b46b7c3303faf1a349bc9 \ + --hash=sha256:9f29c7f0f4b42337ec5a779e166946a9f86d7d56d827e771b69ecbdf426124ac \ + --hash=sha256:9f992e0f916201731993eab8502912878f02287d9f765ef843677ff118d0e0b1 \ + --hash=sha256:a04191a7c8d77e63f6fc1e8336d6c6e93176c0c010833e74410e647f0284f5a1 \ + --hash=sha256:a0f611b431b84f55779cbb7157257d87b4a2876b067c77c4f36b15e44ced65e2 \ + --hash=sha256:a3c2753bf4f48b7a6024e5e8a394af49b1b12c817d75d06942cae03d14ff87b3 \ + --hash=sha256:a5cd7d30e47f87b21362beeb3e86f1b5886e7d9b0294b230dde3d3f4a1591375 \ + --hash=sha256:acc58b7c2e40235712d857fdfc8f2bda9608f4a850d8d9ac0dd1fc80939ca6ac \ + --hash=sha256:adbd67dac4ebf54587198b63cd30c29fd7eafa8c0cab58893d9419414f8efe4b \ + --hash=sha256:b35c35e3923ade1e7ac44e150dec29f5863513246c8bf85e2d7d313e3832bcfb \ + --hash=sha256:c6910eb4ea90c0889f363965cd3c8c45a620ad27b526a7899f0054f6c1b9219e \ + --hash=sha256:cc889fda484d54d0b31feec409406267616536d048a450fc46943e152700bb79 \ + --hash=sha256:ccfd336f96d4c9bbab0309f2a565bf15c468c2d8b2d277a32f89c5940f71fcf9 \ + --hash=sha256:d8e7e8a150e7b548e7ecd6ebb9211c37265991bf2504297d9454e01b58530fc6 \ + --hash=sha256:db09e424d7bb89b6215a184ca93b4f29d7f00ea261b787918a1af74143b98c06 \ + --hash=sha256:e17e7e27af178d31b436dda6a596703b02a89ba74a15e2980c35ecd9909eea3a \ + --hash=sha256:e69290b921b7833c04206f233d6814c60bee1d135b09f5ae5d39229de9b46cd4 \ + --hash=sha256:e8398593ccc4440ce6dffcc4f47d9b2d72b9fe7112ac12ea4a44e7d4de364db1 \ + --hash=sha256:e9d036e343a604db3f5a6c33354018a84a1d3f6dcae3673358b404286204798c \ + --hash=sha256:ea490564435b5b204d8154f0e18387b499ea3cedc1e6af3b3a2ab18291d85aa7 \ + --hash=sha256:f073321a79c81e1a009218a21089f61d87ee5fa3c9563f6be94f8b41ff181812 \ + --hash=sha256:f0cc0b486a56dff72dddae6b6bfa7ff201b0eeac29d4bc6f0e9725dc3c360d71 \ + --hash=sha256:fcf84fe93397a0f67733aa2a38ed4eab9fc6348189fc950e656e1ea198f45668 # via -r requirements.in typing-extensions==4.9.0 \ --hash=sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783 \ diff --git a/tests/core/blacklist/api/requirements.in b/tests/core/blacklist/api/requirements.in index dfea0bebe..9945aad2d 100644 --- a/tests/core/blacklist/api/requirements.in +++ b/tests/core/blacklist/api/requirements.in @@ -1,2 +1,2 @@ -fastapi==0.106.0 +fastapi==0.108.0 uvicorn[standard]==0.25.0 diff --git a/tests/core/blacklist/api/requirements.txt b/tests/core/blacklist/api/requirements.txt index 607a502eb..4b2d26b89 100644 --- a/tests/core/blacklist/api/requirements.txt +++ b/tests/core/blacklist/api/requirements.txt @@ -8,11 +8,10 @@ annotated-types==0.6.0 \ --hash=sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43 \ --hash=sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d # via pydantic -anyio==3.7.1 \ - --hash=sha256:44a3c9aba0f5defa43261a8b3efb97891f2bd7d804e0e1f56419befa1adfc780 \ - --hash=sha256:91dee416e570e92c64041bd18b900d1d6fa78dff7048769ce5ac5ddad004fbb5 +anyio==4.2.0 \ + --hash=sha256:745843b39e829e108e518c489b31dc757de7d2131d53fac32bd8df268227bfee \ + --hash=sha256:e1875bb4b4e2de1669f4bc7869b6d3f54231cdced71605e6e64c9be77e3be50f # via - # fastapi # starlette # watchfiles click==8.1.7 \ @@ -23,9 +22,9 @@ exceptiongroup==1.2.0 \ --hash=sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14 \ --hash=sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68 # via anyio -fastapi==0.106.0 \ - --hash=sha256:193c2f1b495d1d6561a3dc1ca02a150757322247d895ff6bf15b6eefee24feb9 \ - --hash=sha256:c7e7453ac8c4b7414bbafcf90127d743559808eee286ae2c9f99a501f0b534a0 +fastapi==0.108.0 \ + --hash=sha256:5056e504ac6395bf68493d71fcfc5352fdbd5fda6f88c21f6420d80d81163296 \ + --hash=sha256:8c7bc6d315da963ee4cdb605557827071a9a7f95aeb8fcdd3bde48cdc8764dd7 # via -r requirements.in h11==0.14.0 \ --hash=sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d \ @@ -244,14 +243,15 @@ sniffio==1.3.0 \ --hash=sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101 \ --hash=sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384 # via anyio -starlette==0.27.0 \ - --hash=sha256:6a6b0d042acb8d469a01eba54e9cda6cbd24ac602c4cd016723117d6a7e73b75 \ - --hash=sha256:918416370e846586541235ccd38a474c08b80443ed31c578a418e2209b3eef91 +starlette==0.32.0.post1 \ + --hash=sha256:cd0cb10ddb49313f609cedfac62c8c12e56c7314b66d89bb077ba228bada1b09 \ + --hash=sha256:e54e2b7e2fb06dff9eac40133583f10dfa05913f5a85bf26f427c7a40a9a3d02 # via fastapi typing-extensions==4.9.0 \ --hash=sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783 \ --hash=sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd # via + # anyio # fastapi # pydantic # pydantic-core diff --git a/tests/core/bunkernet/api/requirements.in b/tests/core/bunkernet/api/requirements.in index dfea0bebe..9945aad2d 100644 --- a/tests/core/bunkernet/api/requirements.in +++ b/tests/core/bunkernet/api/requirements.in @@ -1,2 +1,2 @@ -fastapi==0.106.0 +fastapi==0.108.0 uvicorn[standard]==0.25.0 diff --git a/tests/core/bunkernet/api/requirements.txt b/tests/core/bunkernet/api/requirements.txt index 607a502eb..4b2d26b89 100644 --- a/tests/core/bunkernet/api/requirements.txt +++ b/tests/core/bunkernet/api/requirements.txt @@ -8,11 +8,10 @@ annotated-types==0.6.0 \ --hash=sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43 \ --hash=sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d # via pydantic -anyio==3.7.1 \ - --hash=sha256:44a3c9aba0f5defa43261a8b3efb97891f2bd7d804e0e1f56419befa1adfc780 \ - --hash=sha256:91dee416e570e92c64041bd18b900d1d6fa78dff7048769ce5ac5ddad004fbb5 +anyio==4.2.0 \ + --hash=sha256:745843b39e829e108e518c489b31dc757de7d2131d53fac32bd8df268227bfee \ + --hash=sha256:e1875bb4b4e2de1669f4bc7869b6d3f54231cdced71605e6e64c9be77e3be50f # via - # fastapi # starlette # watchfiles click==8.1.7 \ @@ -23,9 +22,9 @@ exceptiongroup==1.2.0 \ --hash=sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14 \ --hash=sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68 # via anyio -fastapi==0.106.0 \ - --hash=sha256:193c2f1b495d1d6561a3dc1ca02a150757322247d895ff6bf15b6eefee24feb9 \ - --hash=sha256:c7e7453ac8c4b7414bbafcf90127d743559808eee286ae2c9f99a501f0b534a0 +fastapi==0.108.0 \ + --hash=sha256:5056e504ac6395bf68493d71fcfc5352fdbd5fda6f88c21f6420d80d81163296 \ + --hash=sha256:8c7bc6d315da963ee4cdb605557827071a9a7f95aeb8fcdd3bde48cdc8764dd7 # via -r requirements.in h11==0.14.0 \ --hash=sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d \ @@ -244,14 +243,15 @@ sniffio==1.3.0 \ --hash=sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101 \ --hash=sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384 # via anyio -starlette==0.27.0 \ - --hash=sha256:6a6b0d042acb8d469a01eba54e9cda6cbd24ac602c4cd016723117d6a7e73b75 \ - --hash=sha256:918416370e846586541235ccd38a474c08b80443ed31c578a418e2209b3eef91 +starlette==0.32.0.post1 \ + --hash=sha256:cd0cb10ddb49313f609cedfac62c8c12e56c7314b66d89bb077ba228bada1b09 \ + --hash=sha256:e54e2b7e2fb06dff9eac40133583f10dfa05913f5a85bf26f427c7a40a9a3d02 # via fastapi typing-extensions==4.9.0 \ --hash=sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783 \ --hash=sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd # via + # anyio # fastapi # pydantic # pydantic-core diff --git a/tests/core/db/requirements.in b/tests/core/db/requirements.in index c4e5787e0..c5007d3fb 100644 --- a/tests/core/db/requirements.in +++ b/tests/core/db/requirements.in @@ -1,4 +1,4 @@ cryptography==41.0.7 psycopg2-binary==2.9.9 PyMySQL==1.1.0 -sqlalchemy==2.0.23 +sqlalchemy==2.0.24 diff --git a/tests/core/db/requirements.txt b/tests/core/db/requirements.txt index 9fc2e96b2..74ce73216 100644 --- a/tests/core/db/requirements.txt +++ b/tests/core/db/requirements.txt @@ -225,56 +225,56 @@ pymysql==1.1.0 \ --hash=sha256:4f13a7df8bf36a51e81dd9f3605fede45a4878fe02f9236349fd82a3f0612f96 \ --hash=sha256:8969ec6d763c856f7073c4c64662882675702efcb114b4bcbb955aea3a069fa7 # via -r requirements.in -sqlalchemy==2.0.23 \ - --hash=sha256:0666031df46b9badba9bed00092a1ffa3aa063a5e68fa244acd9f08070e936d3 \ - --hash=sha256:0a8c6aa506893e25a04233bc721c6b6cf844bafd7250535abb56cb6cc1368884 \ - --hash=sha256:0e680527245895aba86afbd5bef6c316831c02aa988d1aad83c47ffe92655e74 \ - --hash=sha256:14aebfe28b99f24f8a4c1346c48bc3d63705b1f919a24c27471136d2f219f02d \ - --hash=sha256:1e018aba8363adb0599e745af245306cb8c46b9ad0a6fc0a86745b6ff7d940fc \ - --hash=sha256:227135ef1e48165f37590b8bfc44ed7ff4c074bf04dc8d6f8e7f1c14a94aa6ca \ - --hash=sha256:31952bbc527d633b9479f5f81e8b9dfada00b91d6baba021a869095f1a97006d \ - --hash=sha256:3e983fa42164577d073778d06d2cc5d020322425a509a08119bdcee70ad856bf \ - --hash=sha256:42d0b0290a8fb0165ea2c2781ae66e95cca6e27a2fbe1016ff8db3112ac1e846 \ - --hash=sha256:42ede90148b73fe4ab4a089f3126b2cfae8cfefc955c8174d697bb46210c8306 \ - --hash=sha256:4895a63e2c271ffc7a81ea424b94060f7b3b03b4ea0cd58ab5bb676ed02f4221 \ - --hash=sha256:4af79c06825e2836de21439cb2a6ce22b2ca129bad74f359bddd173f39582bf5 \ - --hash=sha256:5f94aeb99f43729960638e7468d4688f6efccb837a858b34574e01143cf11f89 \ - --hash=sha256:616fe7bcff0a05098f64b4478b78ec2dfa03225c23734d83d6c169eb41a93e55 \ - --hash=sha256:62d9e964870ea5ade4bc870ac4004c456efe75fb50404c03c5fd61f8bc669a72 \ - --hash=sha256:638c2c0b6b4661a4fd264f6fb804eccd392745c5887f9317feb64bb7cb03b3ea \ - --hash=sha256:63bfc3acc970776036f6d1d0e65faa7473be9f3135d37a463c5eba5efcdb24c8 \ - --hash=sha256:6463aa765cf02b9247e38b35853923edbf2f6fd1963df88706bc1d02410a5577 \ - --hash=sha256:64ac935a90bc479fee77f9463f298943b0e60005fe5de2aa654d9cdef46c54df \ - --hash=sha256:683ef58ca8eea4747737a1c35c11372ffeb84578d3aab8f3e10b1d13d66f2bc4 \ - --hash=sha256:75eefe09e98043cff2fb8af9796e20747ae870c903dc61d41b0c2e55128f958d \ - --hash=sha256:787af80107fb691934a01889ca8f82a44adedbf5ef3d6ad7d0f0b9ac557e0c34 \ - --hash=sha256:7c424983ab447dab126c39d3ce3be5bee95700783204a72549c3dceffe0fc8f4 \ - --hash=sha256:7e0dc9031baa46ad0dd5a269cb7a92a73284d1309228be1d5935dac8fb3cae24 \ - --hash=sha256:87a3d6b53c39cd173990de2f5f4b83431d534a74f0e2f88bd16eabb5667e65c6 \ - --hash=sha256:89a01238fcb9a8af118eaad3ffcc5dedaacbd429dc6fdc43fe430d3a941ff965 \ - --hash=sha256:9585b646ffb048c0250acc7dad92536591ffe35dba624bb8fd9b471e25212a35 \ - --hash=sha256:964971b52daab357d2c0875825e36584d58f536e920f2968df8d581054eada4b \ - --hash=sha256:967c0b71156f793e6662dd839da54f884631755275ed71f1539c95bbada9aaab \ - --hash=sha256:9ca922f305d67605668e93991aaf2c12239c78207bca3b891cd51a4515c72e22 \ - --hash=sha256:a86cb7063e2c9fb8e774f77fbf8475516d270a3e989da55fa05d08089d77f8c4 \ - --hash=sha256:aeb397de65a0a62f14c257f36a726945a7f7bb60253462e8602d9b97b5cbe204 \ - --hash=sha256:b41f5d65b54cdf4934ecede2f41b9c60c9f785620416e8e6c48349ab18643855 \ - --hash=sha256:bd45a5b6c68357578263d74daab6ff9439517f87da63442d244f9f23df56138d \ - --hash=sha256:c14eba45983d2f48f7546bb32b47937ee2cafae353646295f0e99f35b14286ab \ - --hash=sha256:c1bda93cbbe4aa2aa0aa8655c5aeda505cd219ff3e8da91d1d329e143e4aff69 \ - --hash=sha256:c4722f3bc3c1c2fcc3702dbe0016ba31148dd6efcd2a2fd33c1b4897c6a19693 \ - --hash=sha256:c80c38bd2ea35b97cbf7c21aeb129dcbebbf344ee01a7141016ab7b851464f8e \ - --hash=sha256:cabafc7837b6cec61c0e1e5c6d14ef250b675fa9c3060ed8a7e38653bd732ff8 \ - --hash=sha256:cc1d21576f958c42d9aec68eba5c1a7d715e5fc07825a629015fe8e3b0657fb0 \ - --hash=sha256:d0f7fb0c7527c41fa6fcae2be537ac137f636a41b4c5a4c58914541e2f436b45 \ - --hash=sha256:d4041ad05b35f1f4da481f6b811b4af2f29e83af253bf37c3c4582b2c68934ab \ - --hash=sha256:d5578e6863eeb998980c212a39106ea139bdc0b3f73291b96e27c929c90cd8e1 \ - --hash=sha256:e3b5036aa326dc2df50cba3c958e29b291a80f604b1afa4c8ce73e78e1c9f01d \ - --hash=sha256:e599a51acf3cc4d31d1a0cf248d8f8d863b6386d2b6782c5074427ebb7803bda \ - --hash=sha256:f3420d00d2cb42432c1d0e44540ae83185ccbbc67a6054dcc8ab5387add6620b \ - --hash=sha256:f48ed89dd11c3c586f45e9eec1e437b355b3b6f6884ea4a4c3111a3358fd0c18 \ - --hash=sha256:f508ba8f89e0a5ecdfd3761f82dda2a3d7b678a626967608f4273e0dba8f07ac \ - --hash=sha256:fd54601ef9cc455a0c61e5245f690c8a3ad67ddb03d3b91c361d076def0b4c60 +sqlalchemy==2.0.24 \ + --hash=sha256:00d76fe5d7cdb5d84d625ce002ce29fefba0bfd98e212ae66793fed30af73931 \ + --hash=sha256:07cc423892f2ceda9ae1daa28c0355757f362ecc7505b1ab1a3d5d8dc1c44ac6 \ + --hash=sha256:0bb7cedcddffca98c40bb0becd3423e293d1fef442b869da40843d751785beb3 \ + --hash=sha256:1ca7903d5e7db791a355b579c690684fac6304478b68efdc7f2ebdcfe770d8d7 \ + --hash=sha256:1d9b3fd5eca3c0b137a5e0e468e24ca544ed8ca4783e0e55341b7ed2807518ee \ + --hash=sha256:2587e108463cc2e5b45a896b2e7cc8659a517038026922a758bde009271aed11 \ + --hash=sha256:29e51f848f843bbd75d74ae64ab1ab06302cb1dccd4549d1f5afe6b4a946edb2 \ + --hash=sha256:2a479aa1ab199178ff1956b09ca8a0693e70f9c762875d69292d37049ffd0d8f \ + --hash=sha256:37e89d965b52e8b20571b5d44f26e2124b26ab63758bf1b7598a0e38fb2c4005 \ + --hash=sha256:38732884eabc64982a09a846bacf085596ff2371e4e41d20c0734f7e50525d01 \ + --hash=sha256:396f05c552f7fa30a129497c41bef5b4d1423f9af8fe4df0c3dcd38f3e3b9a14 \ + --hash=sha256:4a1d4856861ba9e73bac05030cec5852eabfa9ef4af8e56c19d92de80d46fc34 \ + --hash=sha256:56a0e90a959e18ac5f18c80d0cad9e90cb09322764f536e8a637426afb1cae2f \ + --hash=sha256:57ef6f2cb8b09a042d0dbeaa46a30f2df5dd1e1eb889ba258b0d5d7d6011b81c \ + --hash=sha256:5f801d85ba4753d4ed97181d003e5d3fa330ac7c4587d131f61d7f968f416862 \ + --hash=sha256:6db686a1d9f183c639f7e06a2656af25d4ed438eda581de135d15569f16ace33 \ + --hash=sha256:6db97656fd3fe3f7e5b077f12fa6adb5feb6e0b567a3e99f47ecf5f7ea0a09e3 \ + --hash=sha256:6f5e75de91c754365c098ac08c13fdb267577ce954fa239dd49228b573ca88d7 \ + --hash=sha256:7a6209e689d0ff206c40032b6418e3cfcfc5af044b3f66e381d7f1ae301544b4 \ + --hash=sha256:7ae5d44517fe81079ce75cf10f96978284a6db2642c5932a69c82dbae09f009a \ + --hash=sha256:83fa6df0e035689df89ff77a46bf8738696785d3156c2c61494acdcddc75c69d \ + --hash=sha256:8f358f5cfce04417b6ff738748ca4806fe3d3ae8040fb4e6a0c9a6973ccf9b6e \ + --hash=sha256:9036ebfd934813990c5b9f71f297e77ed4963720db7d7ceec5a3fdb7cd2ef6ce \ + --hash=sha256:95bae3d38f8808d79072da25d5e5a6095f36fe1f9d6c614dd72c59ca8397c7c0 \ + --hash=sha256:9aaaaa846b10dfbe1bda71079d0e31a7e2cebedda9409fa7dba3dfed1ae803e8 \ + --hash=sha256:9b8d0e8578e7f853f45f4512b5c920f6a546cd4bed44137460b2a56534644205 \ + --hash=sha256:9bafaa05b19dc07fa191c1966c5e852af516840b0d7b46b7c3303faf1a349bc9 \ + --hash=sha256:9f29c7f0f4b42337ec5a779e166946a9f86d7d56d827e771b69ecbdf426124ac \ + --hash=sha256:9f992e0f916201731993eab8502912878f02287d9f765ef843677ff118d0e0b1 \ + --hash=sha256:a04191a7c8d77e63f6fc1e8336d6c6e93176c0c010833e74410e647f0284f5a1 \ + --hash=sha256:a0f611b431b84f55779cbb7157257d87b4a2876b067c77c4f36b15e44ced65e2 \ + --hash=sha256:a3c2753bf4f48b7a6024e5e8a394af49b1b12c817d75d06942cae03d14ff87b3 \ + --hash=sha256:a5cd7d30e47f87b21362beeb3e86f1b5886e7d9b0294b230dde3d3f4a1591375 \ + --hash=sha256:acc58b7c2e40235712d857fdfc8f2bda9608f4a850d8d9ac0dd1fc80939ca6ac \ + --hash=sha256:adbd67dac4ebf54587198b63cd30c29fd7eafa8c0cab58893d9419414f8efe4b \ + --hash=sha256:b35c35e3923ade1e7ac44e150dec29f5863513246c8bf85e2d7d313e3832bcfb \ + --hash=sha256:c6910eb4ea90c0889f363965cd3c8c45a620ad27b526a7899f0054f6c1b9219e \ + --hash=sha256:cc889fda484d54d0b31feec409406267616536d048a450fc46943e152700bb79 \ + --hash=sha256:ccfd336f96d4c9bbab0309f2a565bf15c468c2d8b2d277a32f89c5940f71fcf9 \ + --hash=sha256:d8e7e8a150e7b548e7ecd6ebb9211c37265991bf2504297d9454e01b58530fc6 \ + --hash=sha256:db09e424d7bb89b6215a184ca93b4f29d7f00ea261b787918a1af74143b98c06 \ + --hash=sha256:e17e7e27af178d31b436dda6a596703b02a89ba74a15e2980c35ecd9909eea3a \ + --hash=sha256:e69290b921b7833c04206f233d6814c60bee1d135b09f5ae5d39229de9b46cd4 \ + --hash=sha256:e8398593ccc4440ce6dffcc4f47d9b2d72b9fe7112ac12ea4a44e7d4de364db1 \ + --hash=sha256:e9d036e343a604db3f5a6c33354018a84a1d3f6dcae3673358b404286204798c \ + --hash=sha256:ea490564435b5b204d8154f0e18387b499ea3cedc1e6af3b3a2ab18291d85aa7 \ + --hash=sha256:f073321a79c81e1a009218a21089f61d87ee5fa3c9563f6be94f8b41ff181812 \ + --hash=sha256:f0cc0b486a56dff72dddae6b6bfa7ff201b0eeac29d4bc6f0e9725dc3c360d71 \ + --hash=sha256:fcf84fe93397a0f67733aa2a38ed4eab9fc6348189fc950e656e1ea198f45668 # via -r requirements.in typing-extensions==4.9.0 \ --hash=sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783 \ diff --git a/tests/core/greylist/api/requirements.in b/tests/core/greylist/api/requirements.in index dfea0bebe..9945aad2d 100644 --- a/tests/core/greylist/api/requirements.in +++ b/tests/core/greylist/api/requirements.in @@ -1,2 +1,2 @@ -fastapi==0.106.0 +fastapi==0.108.0 uvicorn[standard]==0.25.0 diff --git a/tests/core/greylist/api/requirements.txt b/tests/core/greylist/api/requirements.txt index 607a502eb..4b2d26b89 100644 --- a/tests/core/greylist/api/requirements.txt +++ b/tests/core/greylist/api/requirements.txt @@ -8,11 +8,10 @@ annotated-types==0.6.0 \ --hash=sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43 \ --hash=sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d # via pydantic -anyio==3.7.1 \ - --hash=sha256:44a3c9aba0f5defa43261a8b3efb97891f2bd7d804e0e1f56419befa1adfc780 \ - --hash=sha256:91dee416e570e92c64041bd18b900d1d6fa78dff7048769ce5ac5ddad004fbb5 +anyio==4.2.0 \ + --hash=sha256:745843b39e829e108e518c489b31dc757de7d2131d53fac32bd8df268227bfee \ + --hash=sha256:e1875bb4b4e2de1669f4bc7869b6d3f54231cdced71605e6e64c9be77e3be50f # via - # fastapi # starlette # watchfiles click==8.1.7 \ @@ -23,9 +22,9 @@ exceptiongroup==1.2.0 \ --hash=sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14 \ --hash=sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68 # via anyio -fastapi==0.106.0 \ - --hash=sha256:193c2f1b495d1d6561a3dc1ca02a150757322247d895ff6bf15b6eefee24feb9 \ - --hash=sha256:c7e7453ac8c4b7414bbafcf90127d743559808eee286ae2c9f99a501f0b534a0 +fastapi==0.108.0 \ + --hash=sha256:5056e504ac6395bf68493d71fcfc5352fdbd5fda6f88c21f6420d80d81163296 \ + --hash=sha256:8c7bc6d315da963ee4cdb605557827071a9a7f95aeb8fcdd3bde48cdc8764dd7 # via -r requirements.in h11==0.14.0 \ --hash=sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d \ @@ -244,14 +243,15 @@ sniffio==1.3.0 \ --hash=sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101 \ --hash=sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384 # via anyio -starlette==0.27.0 \ - --hash=sha256:6a6b0d042acb8d469a01eba54e9cda6cbd24ac602c4cd016723117d6a7e73b75 \ - --hash=sha256:918416370e846586541235ccd38a474c08b80443ed31c578a418e2209b3eef91 +starlette==0.32.0.post1 \ + --hash=sha256:cd0cb10ddb49313f609cedfac62c8c12e56c7314b66d89bb077ba228bada1b09 \ + --hash=sha256:e54e2b7e2fb06dff9eac40133583f10dfa05913f5a85bf26f427c7a40a9a3d02 # via fastapi typing-extensions==4.9.0 \ --hash=sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783 \ --hash=sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd # via + # anyio # fastapi # pydantic # pydantic-core diff --git a/tests/core/redis/requirements.in b/tests/core/redis/requirements.in index 530bfcb6f..819a03740 100644 --- a/tests/core/redis/requirements.in +++ b/tests/core/redis/requirements.in @@ -1,4 +1,4 @@ -fastapi==0.106.0 +fastapi==0.108.0 redis==5.0.1 requests==2.31.0 selenium==4.16.0 diff --git a/tests/core/redis/requirements.txt b/tests/core/redis/requirements.txt index 09f793298..d9ccb813e 100644 --- a/tests/core/redis/requirements.txt +++ b/tests/core/redis/requirements.txt @@ -8,11 +8,10 @@ annotated-types==0.6.0 \ --hash=sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43 \ --hash=sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d # via pydantic -anyio==3.7.1 \ - --hash=sha256:44a3c9aba0f5defa43261a8b3efb97891f2bd7d804e0e1f56419befa1adfc780 \ - --hash=sha256:91dee416e570e92c64041bd18b900d1d6fa78dff7048769ce5ac5ddad004fbb5 +anyio==4.2.0 \ + --hash=sha256:745843b39e829e108e518c489b31dc757de7d2131d53fac32bd8df268227bfee \ + --hash=sha256:e1875bb4b4e2de1669f4bc7869b6d3f54231cdced71605e6e64c9be77e3be50f # via - # fastapi # starlette # watchfiles async-timeout==4.0.3 \ @@ -134,9 +133,9 @@ exceptiongroup==1.2.0 \ # anyio # trio # trio-websocket -fastapi==0.106.0 \ - --hash=sha256:193c2f1b495d1d6561a3dc1ca02a150757322247d895ff6bf15b6eefee24feb9 \ - --hash=sha256:c7e7453ac8c4b7414bbafcf90127d743559808eee286ae2c9f99a501f0b534a0 +fastapi==0.108.0 \ + --hash=sha256:5056e504ac6395bf68493d71fcfc5352fdbd5fda6f88c21f6420d80d81163296 \ + --hash=sha256:8c7bc6d315da963ee4cdb605557827071a9a7f95aeb8fcdd3bde48cdc8764dd7 # via -r requirements.in h11==0.14.0 \ --hash=sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d \ @@ -387,9 +386,9 @@ sortedcontainers==2.4.0 \ --hash=sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88 \ --hash=sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0 # via trio -starlette==0.27.0 \ - --hash=sha256:6a6b0d042acb8d469a01eba54e9cda6cbd24ac602c4cd016723117d6a7e73b75 \ - --hash=sha256:918416370e846586541235ccd38a474c08b80443ed31c578a418e2209b3eef91 +starlette==0.32.0.post1 \ + --hash=sha256:cd0cb10ddb49313f609cedfac62c8c12e56c7314b66d89bb077ba228bada1b09 \ + --hash=sha256:e54e2b7e2fb06dff9eac40133583f10dfa05913f5a85bf26f427c7a40a9a3d02 # via fastapi trio==0.23.2 \ --hash=sha256:5a0b566fa5d50cf231cfd6b08f3b03aa4179ff004b8f3144059587039e2b26d3 \ @@ -405,6 +404,7 @@ typing-extensions==4.9.0 \ --hash=sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783 \ --hash=sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd # via + # anyio # fastapi # pydantic # pydantic-core diff --git a/tests/core/reversescan/requirements.in b/tests/core/reversescan/requirements.in index 295927d75..ddf7c36a9 100644 --- a/tests/core/reversescan/requirements.in +++ b/tests/core/reversescan/requirements.in @@ -1,3 +1,3 @@ -fastapi==0.106.0 +fastapi==0.108.0 requests==2.31.0 uvicorn[standard]==0.25.0 diff --git a/tests/core/reversescan/requirements.txt b/tests/core/reversescan/requirements.txt index 72c83e856..d74b6c256 100644 --- a/tests/core/reversescan/requirements.txt +++ b/tests/core/reversescan/requirements.txt @@ -8,11 +8,10 @@ annotated-types==0.6.0 \ --hash=sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43 \ --hash=sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d # via pydantic -anyio==3.7.1 \ - --hash=sha256:44a3c9aba0f5defa43261a8b3efb97891f2bd7d804e0e1f56419befa1adfc780 \ - --hash=sha256:91dee416e570e92c64041bd18b900d1d6fa78dff7048769ce5ac5ddad004fbb5 +anyio==4.2.0 \ + --hash=sha256:745843b39e829e108e518c489b31dc757de7d2131d53fac32bd8df268227bfee \ + --hash=sha256:e1875bb4b4e2de1669f4bc7869b6d3f54231cdced71605e6e64c9be77e3be50f # via - # fastapi # starlette # watchfiles certifi==2023.11.17 \ @@ -119,9 +118,9 @@ exceptiongroup==1.2.0 \ --hash=sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14 \ --hash=sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68 # via anyio -fastapi==0.106.0 \ - --hash=sha256:193c2f1b495d1d6561a3dc1ca02a150757322247d895ff6bf15b6eefee24feb9 \ - --hash=sha256:c7e7453ac8c4b7414bbafcf90127d743559808eee286ae2c9f99a501f0b534a0 +fastapi==0.108.0 \ + --hash=sha256:5056e504ac6395bf68493d71fcfc5352fdbd5fda6f88c21f6420d80d81163296 \ + --hash=sha256:8c7bc6d315da963ee4cdb605557827071a9a7f95aeb8fcdd3bde48cdc8764dd7 # via -r requirements.in h11==0.14.0 \ --hash=sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d \ @@ -346,14 +345,15 @@ sniffio==1.3.0 \ --hash=sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101 \ --hash=sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384 # via anyio -starlette==0.27.0 \ - --hash=sha256:6a6b0d042acb8d469a01eba54e9cda6cbd24ac602c4cd016723117d6a7e73b75 \ - --hash=sha256:918416370e846586541235ccd38a474c08b80443ed31c578a418e2209b3eef91 +starlette==0.32.0.post1 \ + --hash=sha256:cd0cb10ddb49313f609cedfac62c8c12e56c7314b66d89bb077ba228bada1b09 \ + --hash=sha256:e54e2b7e2fb06dff9eac40133583f10dfa05913f5a85bf26f427c7a40a9a3d02 # via fastapi typing-extensions==4.9.0 \ --hash=sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783 \ --hash=sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd # via + # anyio # fastapi # pydantic # pydantic-core diff --git a/tests/core/whitelist/api/requirements.in b/tests/core/whitelist/api/requirements.in index dfea0bebe..9945aad2d 100644 --- a/tests/core/whitelist/api/requirements.in +++ b/tests/core/whitelist/api/requirements.in @@ -1,2 +1,2 @@ -fastapi==0.106.0 +fastapi==0.108.0 uvicorn[standard]==0.25.0 diff --git a/tests/core/whitelist/api/requirements.txt b/tests/core/whitelist/api/requirements.txt index 607a502eb..4b2d26b89 100644 --- a/tests/core/whitelist/api/requirements.txt +++ b/tests/core/whitelist/api/requirements.txt @@ -8,11 +8,10 @@ annotated-types==0.6.0 \ --hash=sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43 \ --hash=sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d # via pydantic -anyio==3.7.1 \ - --hash=sha256:44a3c9aba0f5defa43261a8b3efb97891f2bd7d804e0e1f56419befa1adfc780 \ - --hash=sha256:91dee416e570e92c64041bd18b900d1d6fa78dff7048769ce5ac5ddad004fbb5 +anyio==4.2.0 \ + --hash=sha256:745843b39e829e108e518c489b31dc757de7d2131d53fac32bd8df268227bfee \ + --hash=sha256:e1875bb4b4e2de1669f4bc7869b6d3f54231cdced71605e6e64c9be77e3be50f # via - # fastapi # starlette # watchfiles click==8.1.7 \ @@ -23,9 +22,9 @@ exceptiongroup==1.2.0 \ --hash=sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14 \ --hash=sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68 # via anyio -fastapi==0.106.0 \ - --hash=sha256:193c2f1b495d1d6561a3dc1ca02a150757322247d895ff6bf15b6eefee24feb9 \ - --hash=sha256:c7e7453ac8c4b7414bbafcf90127d743559808eee286ae2c9f99a501f0b534a0 +fastapi==0.108.0 \ + --hash=sha256:5056e504ac6395bf68493d71fcfc5352fdbd5fda6f88c21f6420d80d81163296 \ + --hash=sha256:8c7bc6d315da963ee4cdb605557827071a9a7f95aeb8fcdd3bde48cdc8764dd7 # via -r requirements.in h11==0.14.0 \ --hash=sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d \ @@ -244,14 +243,15 @@ sniffio==1.3.0 \ --hash=sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101 \ --hash=sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384 # via anyio -starlette==0.27.0 \ - --hash=sha256:6a6b0d042acb8d469a01eba54e9cda6cbd24ac602c4cd016723117d6a7e73b75 \ - --hash=sha256:918416370e846586541235ccd38a474c08b80443ed31c578a418e2209b3eef91 +starlette==0.32.0.post1 \ + --hash=sha256:cd0cb10ddb49313f609cedfac62c8c12e56c7314b66d89bb077ba228bada1b09 \ + --hash=sha256:e54e2b7e2fb06dff9eac40133583f10dfa05913f5a85bf26f427c7a40a9a3d02 # via fastapi typing-extensions==4.9.0 \ --hash=sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783 \ --hash=sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd # via + # anyio # fastapi # pydantic # pydantic-core From 80f8d15482b7a49f958ba4b6b0d62ef9e2654245 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophile=20Diot?= Date: Fri, 29 Dec 2023 12:35:40 +0000 Subject: [PATCH 04/11] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d17defca3..b787474c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - [BUGFIX] Fix ModSecurity-nginx to make it work with brotli - [FEATURE] Add Anonymous reporting feature - [FEATURE] Add support for fallback Referrer-Policies +- [FEATURE] Add profile page to web ui and the possibility to activate the 2FA - [MISC] Fallback to default HTTPS certificate to prevent errors - [MISC] Updated Python Docker image to 3.12.1-alpine3.18 in Dockerfiles - [DEPS] Updated ModSecurity to v3.0.11 From 116ca222604b73017f6af3e55487e37b6905992e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophile=20Diot?= Date: Fri, 29 Dec 2023 12:36:04 +0000 Subject: [PATCH 05/11] Update lua-resty-openssl to version v1.2.0 --- src/deps/deps.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/deps/deps.json b/src/deps/deps.json index 582a5b50d..589147007 100644 --- a/src/deps/deps.json +++ b/src/deps/deps.json @@ -151,9 +151,9 @@ }, { "id": "lua-resty-openssl", - "name": "lua-resty-openssl v1.0.2", + "name": "lua-resty-openssl v1.2.0", "url": "https://github.com/fffonion/lua-resty-openssl.git", - "commit": "5aba923e78ae0f213f3b4719effa879e3971821f", + "commit": "7f25f00ba2b2140b794c94b5ae17f5a0736e3b03", "post_install": "rm -r src/deps/src/lua-resty-openssl/t" }, { From dda63ddceeb1f4ffdd97d6aa95ac24a1a7eeede7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophile=20Diot?= Date: Fri, 29 Dec 2023 12:36:57 +0000 Subject: [PATCH 06/11] Squashed 'src/deps/src/lua-resty-openssl/' changes from 5aba923e7..7f25f00ba 7f25f00ba release: 1.2.0 40fdbbbdd feat(mac) add reset API b36ccba3f feat(openssl) list functions can now optionally drop provider name 5381f10c3 chore(tests) bump openssl to 3.2.0 (#140) b72870ce1 chore(perf) calculate openssl speed numbers d23b34ae8 fix(compat) works better with plain luajit e9edc76cb tests(perf) add kdf dac54bf76 perf(kdf) use table.nkeys for params 3d0a51cca feat(cipher) add set_buffer_size API ba5de3e53 perf(cipher) improve performance on cipher e87e93f66 tests(perf) pretty up tests c8745f9ba chore(tests) format tests 073c943bf feat(bn) add from_mpi, to_mpi and set API 253d11c54 release: 1.1.0 2e401b335 feat(pkey) support pass in ctrl str options 12f5209ff chore(tests) revert BoringSSL specific patterns d155657e6 feat(err) standardize error format and add new API to get reason and library name 3c0027d0b doc(readme) remove docs about BoringSSL git-subtree-dir: src/deps/src/lua-resty-openssl git-subtree-split: 7f25f00ba2b2140b794c94b5ae17f5a0736e3b03 --- .github/workflows/tests.yml | 54 +- CHANGELOG.md | 29 +- README.md | 303 ++- examples/perf/framework.lua | 65 +- examples/perf/test_cipher.lua | 3 + examples/perf/test_other_libs.lua | 433 ++++ examples/perf/test_pkey_asymm.lua | 4 + examples/perf/test_pkey_codec.lua | 7 +- examples/perf/test_x509_codec.lua | 7 +- lib/resty/openssl.lua | 70 +- lib/resty/openssl/auxiliary/compat.lua | 84 + lib/resty/openssl/auxiliary/jwk.lua | 31 +- lib/resty/openssl/bn.lua | 167 +- lib/resty/openssl/cipher.lua | 79 +- lib/resty/openssl/ctx.lua | 4 +- lib/resty/openssl/err.lua | 79 +- lib/resty/openssl/include/bn.lua | 13 +- lib/resty/openssl/include/err.lua | 25 +- lib/resty/openssl/include/evp.lua | 33 +- lib/resty/openssl/include/evp/pkey.lua | 49 +- lib/resty/openssl/kdf.lua | 15 +- lib/resty/openssl/mac.lua | 22 +- lib/resty/openssl/param.lua | 4 +- lib/resty/openssl/pkey.lua | 127 +- lib/resty/openssl/version.lua | 80 +- ...spec => lua-resty-openssl-1.2.0-1.rockspec | 5 +- scripts/templates/x509_tests.j2 | 35 +- scripts/types_test.py | 2 +- t/fips.t | 7 + t/openssl.t | 17 +- t/openssl/asn1.t | 9 + t/openssl/bn.t | 385 ++-- t/openssl/cipher.t | 60 +- t/openssl/ctx.t | 4 + t/openssl/digest.t | 17 +- t/openssl/err.t | 1 + t/openssl/helper.lua | 2 +- t/openssl/hmac.t | 10 +- t/openssl/kdf.t | 21 +- t/openssl/mac.t | 13 + t/openssl/objects.t | 6 +- t/openssl/param.t | 1 + t/openssl/pkcs12.t | 37 +- t/openssl/pkey.t | 1768 +++++++++-------- t/openssl/provider.t | 12 +- t/openssl/rand.t | 4 +- t/openssl/version.t | 7 +- t/openssl/x509.t | 112 +- t/openssl/x509/altname.t | 17 +- t/openssl/x509/chain.t | 13 +- t/openssl/x509/crl.t | 41 +- t/openssl/x509/csr.t | 75 +- t/openssl/x509/extension.t | 23 +- t/openssl/x509/extensions.t | 11 + t/openssl/x509/name.t | 8 +- t/openssl/x509/revoked.t | 5 +- t/openssl/x509/store.t | 25 +- 57 files changed, 3058 insertions(+), 1482 deletions(-) create mode 100644 examples/perf/test_other_libs.lua create mode 100644 lib/resty/openssl/auxiliary/compat.lua rename lua-resty-openssl-1.0.2-1.rockspec => lua-resty-openssl-1.2.0-1.rockspec (98%) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 1a7f23f78..b673a9058 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -60,7 +60,7 @@ jobs: lua_resty_core: "v0.1.27" nginx_cc_opts: "-Wno-error" - nginx: "1.21.4" - openssl: "3.2.0-alpha1" + openssl: "3.2.0" openssl_fips: "3.0.8" extras: "valgrind perf" lua_nginx_module: "v0.10.25" @@ -117,7 +117,6 @@ jobs: popd git clone https://github.com/openresty/lua-resty-core.git ../lua-resty-core -b ${{ matrix.lua_resty_core }} git clone https://github.com/openresty/lua-resty-lrucache.git ../lua-resty-lrucache - git clone https://github.com/jkeys089/lua-resty-hmac ../lua-resty-hmac && pushd ../lua-resty-hmac && git checkout 79a4929 && popd git clone https://github.com/openresty/lua-resty-string ../lua-resty-string - name: Build OpenSSL @@ -181,20 +180,6 @@ jobs: nginx -V ldd `which nginx`|grep -E 'luajit|ssl|pcre' - - name: Run performance test - if: contains(matrix.extras, 'perf') - run: | - wget https://github.com/openresty/resty-cli/raw/master/bin/resty - chmod +x resty - - export LD_LIBRARY_PATH=$LUAJIT_LIB:$LD_LIBRARY_PATH - export PATH=$BASE_PATH/work/nginx/sbin:$PATH - - for f in $(find examples/perf -type f -name "test_*" | sort); do - ./resty --no-stream -I lib $f - echo '================================================================' - done - - name: Run Test run: | export LD_LIBRARY_PATH=$LUAJIT_LIB:$LD_LIBRARY_PATH @@ -242,4 +227,39 @@ jobs: else echo "FIPS tests are skipped" fi - + + - name: Prepare other libraries + if: contains(matrix.extras, 'perf') + run: | + git clone https://github.com/spacewander/lua-resty-rsa ../lua-resty-rsa + + wget https://luarocks.org/releases/luarocks-3.9.2.tar.gz + tar zxf luarocks-*.tar.gz + pushd luarocks-*/ + ./configure --with-lua=$LUAJIT_PREFIX \ + --lua-suffix=jit \ + --with-lua-include=$LUAJIT_PREFIX/include/luajit-2.1 + make -j$(nproc) build + sudo make install + popd + + luarocks install --local lua_pack + luarocks install --local openssl OPENSSL_DIR=$OPENSSL_PREFIX + luarocks install --local luaossl CRYPTO_DIR=$OPENSSL_PREFIX OPENSSL_DIR=$OPENSSL_PREFIX + cp ~/.luarocks/lib/lua/5.1/openssl_*-openssl.so ~/.luarocks/lib/lua/5.1/lua-openssl.so + + - name: Run performance test + if: contains(matrix.extras, 'perf') + run: | + wget https://github.com/openresty/resty-cli/raw/master/bin/resty + chmod +x resty + + export LD_LIBRARY_PATH=$LUAJIT_LIB:$LD_LIBRARY_PATH + export PATH=$BASE_PATH/work/nginx/sbin:$PATH + + for f in $(find examples/perf -type f -name "test_*" | sort); do + ./resty --no-stream -I lib -I ../lua-resty-string/lib -I ../lua-resty-rsa/lib -I ~/.luarocks/lib/lua/5.1 $f + echo '================================================================' + done + + diff --git a/CHANGELOG.md b/CHANGELOG.md index 67ea9c876..5afde5e29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,29 @@ ## [Unreleased] + +## [1.2.0] - 2023-12-28 +### bug fixes +- **compat:** works better with plain luajit [d23b34a](https://github.com/fffonion/lua-resty-openssl/commit/d23b34ae8b3349342d5f82d90dbfe76696dd2ca4) + +### features +- **bn:** add from_mpi, to_mpi and set API [073c943](https://github.com/fffonion/lua-resty-openssl/commit/073c943bf74cce7bd6ce90ee97dfc9b753af3cf2) +- **cipher:** add set_buffer_size API [3d0a51c](https://github.com/fffonion/lua-resty-openssl/commit/3d0a51ccab0c2dd46f9eb8088fa2f767eff02a61) +- **mac:** add reset API [40fdbbb](https://github.com/fffonion/lua-resty-openssl/commit/40fdbbbddc078c01ea40b8ec8b21257d0e3fefa6) +- **openssl:** list functions can now optionally drop provider name [b36ccba](https://github.com/fffonion/lua-resty-openssl/commit/b36ccba3fce9a1b51a0bc8c23d5e9843e99a2052) + +### performance improvements +- **cipher:** improve performance on cipher [ba5de3e](https://github.com/fffonion/lua-resty-openssl/commit/ba5de3e53e1b83de5b8f75d64c83eb3e507f386a) +- **kdf:** use table.nkeys for params [dac54bf](https://github.com/fffonion/lua-resty-openssl/commit/dac54bf7685d907518e80ab96a594753cdf0c0e1) + + + +## [1.1.0] - 2023-12-15 +### features +- **err:** standardize error format and add new API to get reason and library name [d155657](https://github.com/fffonion/lua-resty-openssl/commit/d155657e60cdfdb0634d0c3147b184e8543b972e) +- **pkey:** support pass in ctrl str options [2e401b3](https://github.com/fffonion/lua-resty-openssl/commit/2e401b335bce759fe8a7a48d5b23cb33a46cc9ba) + + ## [1.0.2] - 2023-11-21 ### bug fixes @@ -459,8 +482,8 @@ - **autogen:** generate tests for x509, csr and crl [1392428](https://github.com/fffonion/lua-resty-openssl/commit/1392428352164d2a1a6e0c03075ff65b55aecdee) - **objects:** add helper function for ASN1_OBJECT [d037706](https://github.com/fffonion/lua-resty-openssl/commit/d037706c11d716afe3616bdaf4658afc1763081d) - **pkey:** asymmetric encryption and decryption [6d60451](https://github.com/fffonion/lua-resty-openssl/commit/6d60451157edbf9cefb634f888dfa3e6d9be302f) -- **x509:** getter/setters for extensions [243f40d](https://github.com/fffonion/lua-resty-openssl/commit/243f40d35562a516f404188a5c7eb8f5134d9b30) - **x509:** add get_ocsp_url and get_crl_url [6141b6f](https://github.com/fffonion/lua-resty-openssl/commit/6141b6f5aed38706b477a71d8c4383bf55da7eee) +- **x509:** getter/setters for extensions [243f40d](https://github.com/fffonion/lua-resty-openssl/commit/243f40d35562a516f404188a5c7eb8f5134d9b30) - **x509.altname:** support iterate and decode over the stack [083a201](https://github.com/fffonion/lua-resty-openssl/commit/083a201746e02d51f6c5c640ad9bf8c6730ebe0b) - **x509.crl:** add crl module [242f8cb](https://github.com/fffonion/lua-resty-openssl/commit/242f8cb45d6c2df5918f26540c92a430d42feb5d) - **x509.csr:** autogen some csr functions as well [9800e36](https://github.com/fffonion/lua-resty-openssl/commit/9800e36c2ff8a299b88f24091cc722940a8652bb) @@ -548,7 +571,9 @@ - **x509:** export pubkey [ede4f81](https://github.com/fffonion/lua-resty-openssl/commit/ede4f817cb0fe092ad6f9ab5d6ecdcde864a9fd8) -[Unreleased]: https://github.com/fffonion/lua-resty-openssl/compare/1.0.2...HEAD +[Unreleased]: https://github.com/fffonion/lua-resty-openssl/compare/1.2.0...HEAD +[1.2.0]: https://github.com/fffonion/lua-resty-openssl/compare/1.1.0...1.2.0 +[1.1.0]: https://github.com/fffonion/lua-resty-openssl/compare/1.0.2...1.1.0 [1.0.2]: https://github.com/fffonion/lua-resty-openssl/compare/1.0.1...1.0.2 [1.0.1]: https://github.com/fffonion/lua-resty-openssl/compare/1.0.0...1.0.1 [1.0.0]: https://github.com/fffonion/lua-resty-openssl/compare/0.8.26...1.0.0 diff --git a/README.md b/README.md index 7a6ed283c..41c0a157b 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,11 @@ Table of Contents * [resty.openssl.ctx](#restyopensslctx) + [ctx.new](#ctxnew) + [ctx.free](#ctxfree) + * [resty.openssl.err](#restyopensslerr) + + [err.format_error](#errformat_error) + + [err.get_last_error_code](#errget_last_error_code) + + [err.get_lib_error_string](#errget_lib_error_string) + + [err.get_reason_error_string](#errget_reason_error_string) * [resty.openssl.version](#restyopensslversion) + [version_num](#version_num) + [version_text](#version_text) @@ -69,7 +74,9 @@ Table of Contents + [bn.new](#bnnew) + [bn.dup](#bndup) + [bn.istype](#bnistype) + + [bn:set](#bnset) + [bn.from_binary, bn:to_binary](#bnfrom_binary-bnto_binary) + + [bn.from_mpi, bn:to_mpi](#bnfrom_mpi-bnto_mpi) + [bn.from_hex, bn:to_hex](#bnfrom_hex-bnto_hex) + [bn.from_dec, bn:to_dec](#bnfrom_dec-bnto_dec) + [bn:to_number](#bnto_number) @@ -84,6 +91,7 @@ Table of Contents * [resty.openssl.cipher](#restyopensslcipher) + [cipher.new](#ciphernew) + [cipher.istype](#cipheristype) + + [cipher.set_buffer_size](#cipherset_buffer_size) + [cipher:get_provider_name](#cipherget_provider_name) + [cipher:gettable_params, cipher:settable_params, cipher:get_param, cipher:set_params](#ciphergettable_params-ciphersettable_params-cipherget_param-cipherset_params) + [cipher:encrypt](#cipherencrypt) @@ -116,6 +124,7 @@ Table of Contents + [mac:gettable_params, mac:settable_params, mac:get_param, mac:set_params](#macgettable_params-macsettable_params-macget_param-macset_params) + [mac:update](#macupdate) + [mac:final](#macfinal) + + [mac:reset](#macreset) * [resty.openssl.kdf](#restyopensslkdf) + [kdf.derive (legacy)](#kdfderive-legacy) + [kdf.new](#kdfnew) @@ -406,7 +415,7 @@ lua-resty-openssl supports following modes: Compile the module per [security policy](https://www.openssl.org/docs/fips/SecurityPolicy-2.0.2.pdf), -**OpenSSL 3.0.0 fips provider ** +**OpenSSL 3.0.0 fips provider** Refer to https://wiki.openssl.org/index.php/OpenSSL_3.0 Section 7 Compile the provider per guide, install the fipsmodule.cnf that @@ -432,12 +441,6 @@ local c = assert(cipher.new("aes256", "fips=yes")) print(c:get_provider_name()) -- prints "fips" ``` -**BroingSSL fips-20190808 and fips-20210429 (later haven't been certified)** - -Compile the module per [security policy](https://csrc.nist.gov/CSRC/media/projects/cryptographic-module-validation-program/documents/security-policies/140sp3678.pdf) - -Check if FIPS is acticated by running `assert(openssl.set_fips_mode(true))`. - [Back to TOC](#table-of-contents) ### openssl.get_fips_version_text @@ -458,33 +461,37 @@ Sets the default properties for all future EVP algorithm fetches, implicit as we ### openssl.list_cipher_algorithms -**syntax**: *ret = openssl.list_cipher_algorithms()* +**syntax**: *ret = openssl.list_cipher_algorithms(hide_provider?)* -Return available cipher algorithms in an array. +Return available cipher algorithms in an array. Set `hide_provider` to `true` to +hide provider name from the result. [Back to TOC](#table-of-contents) ### openssl.list_digest_algorithms -**syntax**: *ret = openssl.list_digest_algorithms()* +**syntax**: *ret = openssl.list_digest_algorithms(hide_provider?)* -Return available digest algorithms in an array. +Return available digest algorithms in an array. Set `hide_provider` to `true` to +hide provider name from the result. [Back to TOC](#table-of-contents) ### openssl.list_mac_algorithms -**syntax**: *ret = openssl.list_mac_algorithms()* +**syntax**: *ret = openssl.list_mac_algorithms(hide_provider?)* -Return available MAC algorithms in an array. +Return available MAC algorithms in an array. Set `hide_provider` to `true` to +hide provider name from the result. [Back to TOC](#table-of-contents) ### openssl.list_kdf_algorithms -**syntax**: *ret = openssl.list_kdf_algorithms()* +**syntax**: *ret = openssl.list_kdf_algorithms(hide_provider?)* -Return available KDF algorithms in an array. +Return available KDF algorithms in an array. Set `hide_provider` to `true` to +hide provider name from the result. [Back to TOC](#table-of-contents) @@ -562,6 +569,71 @@ Free the context that was previously created by [ctx.new](#ctxnew). [Back to TOC](#table-of-contents) +## resty.openssl.err + +A module to provide error messages. + +[Back to TOC](#table-of-contents) + +### err.format_error + +**syntax**: *msg = err.format_error(ctx_msg?, return_code?, all_errors?)* + +**syntax**: *msg = err.format_all_errors(ctx_msg?, return_code?)* + +Return the latest error message from the last error code. Errors are formatted as: + + [ctx_msg]: code: [return_code]: error:[error code]:[library name]:[func name]:[reason string]:[file name]:[line number]: + +On OpenSSL prior to 3.x, errors are formatted as: + + [ctx_msg]: code: [return_code]: [file name]:[line number]:error:[error code]:[library name]:[func name]:[reason string]: + + +If `all_errors` is set to `true`, all errors no just the latest one will be returned in a single string. All errors thrown +by this library internally only thrown the latest error. + +For example: + +```lua +local f = io.open("t/fixtures/ec_key_encrypted.pem"):read("*a") +local privkey, err = require("resty.openssl.pkey").new(f, { + format = "PEM", + type = "pr", + passphrase = "wrongpasswrod", +}) +ngx.say(err) +-- pkey.new:load_key: error:4800065:PEM routines:PEM_do_header:bad decrypt:crypto/pem/pem_lib.c:467: +``` + +[Back to TOC](#table-of-contents) + +### err.get_last_error_code + +**syntax**: *code = err.get_last_error_code()* + +Return the last error code. + +[Back to TOC](#table-of-contents) + +### err.get_lib_error_string + +**syntax**: *lib_error_message = err.get_lib_error_string(code?)* + +Return the library name of the last error code as string. If `code` is set, return the library name +corresponding to provided error code instead. + +[Back to TOC](#table-of-contents) + +### err.get_reason_error_string + +**syntax**: *reason_error_message = err.get_reason_error_string(code?)* + +Return the reason of the last error code as string. If `code` is set, return the reason +corresponding to provided error code instead. + +[Back to TOC](#table-of-contents) + ## resty.openssl.version A module to provide version info. @@ -796,6 +868,8 @@ in provided JSON will decide if a private or public key is loaded. from private key part (the `d` parameter) if it's specified. - Signatures and verification must use `ecdsa_use_raw` option to work with JWS standards for EC keys. See [pkey:sign](#pkeysign) and [pkey.verify](#pkeyverify) for detail. +- When running outside of OpenResty, needs to install a JSON library (`cjson` or `dkjson`) +and `basexx`. #### Key generation @@ -842,6 +916,26 @@ local key, err = pkey.new({ }) ``` +It's also possible to pass raw pkeyopt control strings in `config` table as used in the `genpkey` CLI program. +See [openssl-genpkey(1)](https://www.openssl.org/docs/man3.0/man1/openssl-genpkey.html) for a list of options. + +For example: + +```lua +pkey.new({ + type = 'RSA', + bits = 2048, + exp = 65537, +}) +-- is same as +pkey.new({ + type = 'RSA', + exp = 65537, + "rsa_keygen_bits:4096", +}) + +``` + [Back to TOC](#table-of-contents) @@ -893,6 +987,9 @@ local pem, err = pkey.paramgen({ }) ``` +It's also possible to pass raw pkeyopt control strings in `config` table as used in the `genpkey` CLI program. +See [openssl-genpkey(1)](https://www.openssl.org/docs/man3.0/man1/openssl-genpkey.html) for a list of options. + [Back to TOC](#table-of-contents) ### pkey:get_provider_name @@ -1047,10 +1144,20 @@ to use when signing. When `md_alg` is undefined, for RSA and EC keys, this funct by default. For Ed25519 or Ed448 keys, this function does a PureEdDSA signing, no message digest should be specified and will not be used. -`opts` is a table that accepts additional parameters. +For RSA key, it's also possible to specify `padding` scheme with following choices: -For RSA key, it's also possible to specify `padding` scheme. The choice of values are same -as those in [pkey:encrypt](#pkeyencrypt). When `padding` is `RSA_PKCS1_PSS_PADDING`, it's +```lua + pkey.PADDINGS = { + RSA_PKCS1_PADDING = 1, + RSA_SSLV23_PADDING = 2, + RSA_NO_PADDING = 3, + RSA_PKCS1_OAEP_PADDING = 4, + RSA_X931_PADDING = 5, -- sign only + RSA_PKCS1_PSS_PADDING = 6, -- sign and verify only + } +``` + +When `padding` is `RSA_PKCS1_PSS_PADDING`, it's possible to specify PSS salt length by setting `opts.pss_saltlen`. For EC key, this function does a ECDSA signing. @@ -1062,6 +1169,32 @@ is encoded in ASN.1 DER format. If the `opts` table contains a `ecdsa_use_raw` f a true value, a binary with just the concatenation of binary representation `pr` and `ps` is returned. This is useful for example to send the signature as JWS. +`opts` is a table that accepts additional parameters with following choices: + +``` +{ + pss_saltlen, -- For PSS mode only this option specifies the salt length. + mgf1_md, -- For PSS and OAEP padding sets the MGF1 digest. If the MGF1 digest is not explicitly set in PSS mode then the signing digest is used. + oaep_md, -- The digest used for the OAEP hash function. If not explicitly set then SHA1 is used. +} +``` + +It's also possible to pass raw pkeyopt control strings as used in the `pkeyutl` CLI program. This lets user pass in options that +are not explictly supported as parameters above. +See [openssl-pkeyutl(1)](https://www.openssl.org/docs/manmaster/man1/openssl-pkeyutl.html) for a list of options. + +```lua +pk:sign(message, nil, pk.PADDINGS.RSA_PKCS1_OAEP_PADDING, { + oaep_md = "sha256", +}) +-- is same as +pk:sign(message, nil, nil, { + "rsa_padding_mode:oaep", + "rsa_oaep_md:sha256", +}) +-- in pkeyutl CLI the above is equivalent to: `openssl pkeyutl -sign -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha256 +``` + [Back to TOC](#table-of-contents) ### pkey:verify @@ -1084,10 +1217,8 @@ to use when verifying. When `md_alg` is undefined, for RSA and EC keys, this fun by default. For Ed25519 or Ed448 keys, this function does a PureEdDSA verification, no message digest should be specified and will not be used. -`opts` is a table that accepts additional parameters. - -For RSA key, it's also possible to specify `padding` scheme. The choice of values are same -as those in [pkey:encrypt](#pkeyencrypt). When `padding` is `RSA_PKCS1_PSS_PADDING`, it's +When key is a RSA key, the function accepts an optional argument `padding` which choices +of values are same as those in [pkey:sign](#pkeysign). When `padding` is `RSA_PKCS1_PSS_PADDING`, it's possible to specify PSS salt length by setting `opts.pss_saltlen`. For EC key, this function does a ECDSA verification. Normally, the ECDSA signature @@ -1095,6 +1226,10 @@ should be encoded in ASN.1 DER format. If the `opts` table contains a `ecdsa_use a true value, this library treat `signature` as concatenation of binary representation `pr` and `ps`. This is useful for example to verify the signature as JWS. +`opts` is a table that accepts additional parameters which choices +of values are same as those in [pkey:sign](#pkeysign). + + ```lua -- RSA and EC keys local pk, err = require("resty.openssl.pkey").new() @@ -1130,34 +1265,28 @@ ngx.say(ngx.encode_base64(signature)) ### pkey:encrypt -**syntax**: *cipher_txt, err = pk:encrypt(txt, padding?)* +**syntax**: *cipher_txt, err = pk:encrypt(txt, padding?, opts?)* Encrypts plain text `txt` with `pkey` instance, which must loaded a public key. -When key is a RSA key, the function accepts an optional second argument `padding` which can be: - -```lua - pkey.PADDINGS = { - RSA_PKCS1_PADDING = 1, - RSA_SSLV23_PADDING = 2, - RSA_NO_PADDING = 3, - RSA_PKCS1_OAEP_PADDING = 4, - RSA_X931_PADDING = 5, - RSA_PKCS1_PSS_PADDING = 6, - } -``` - +The optional second argument `padding` has same meaning as in [pkey:sign](#pkeysign). If omitted, `padding` is default to `pkey.PADDINGS.RSA_PKCS1_PADDING`. +The third optional argument `opts` has same meaning as in [pkey:sign](#pkeysign). + + [Back to TOC](#table-of-contents) ### pkey:decrypt -**syntax**: *txt, err = pk:decrypt(cipher_txt, padding?)* +**syntax**: *txt, err = pk:decrypt(cipher_txt, padding?, opts?)* Decrypts cipher text `cipher_txt` with pkey instance, which must loaded a private key. -The optional second argument `padding` has same meaning in [pkey:encrypt](#pkeyencrypt). +The optional second argument `padding` has same meaning as in [pkey:sign](#pkeysign). +If omitted, `padding` is default to `pkey.PADDINGS.RSA_PKCS1_PADDING`. + +The third optional argument `opts` has same meaning as in [pkey:sign](#pkeysign). ```lua local pkey = require("resty.openssl.pkey") @@ -1176,11 +1305,14 @@ ngx.say(decrypted) ### pkey:sign_raw -**syntax**: *signature, err = pk:sign_raw(txt, padding?)* +**syntax**: *signature, err = pk:sign_raw(txt, padding?, opts?)* Signs the cipher text `cipher_txt` with pkey instance, which must loaded a private key. -The optional second argument `padding` has same meaning in [pkey:encrypt](#pkeyencrypt). +The optional second argument `padding` has same meaning as in [pkey:sign](#pkeysign). +If omitted, `padding` is default to `pkey.PADDINGS.RSA_PKCS1_PADDING`. + +The third optional argument `opts` has same meaning as in [pkey:sign](#pkeysign). This function may also be called "private encrypt" in some implementations like NodeJS or PHP. Do note as the function names suggested, this function is not secure to be regarded as an encryption. @@ -1194,12 +1326,15 @@ for an example. ### pkey:verify_recover -**syntax**: *txt, err = pk:verify_recover(signature, padding?)* +**syntax**: *txt, err = pk:verify_recover(signature, padding?, opts?)* Verify the cipher text `signature` with pkey instance, which must loaded a public key, and also returns the original text being signed. This operation is only supported by RSA key. -The optional second argument `padding` has same meaning in [pkey:encrypt](#pkeyencrypt). +The optional second argument `padding` has same meaning as in [pkey:sign](#pkeysign). +If omitted, `padding` is default to `pkey.PADDINGS.RSA_PKCS1_PADDING`. + +The third optional argument `opts` has same meaning as in [pkey:sign](#pkeysign). This function may also be called "public decrypt" in some implementations like NodeJS or PHP. @@ -1255,8 +1390,20 @@ Module to expose BIGNUM structure. Note bignum is a big integer, no float operat **syntax**: *b, err = bn.new(number?)* -Creates a `bn` instance. The first argument can be a Lua number or `nil` to -creates an empty instance. +**syntax**: *b, err = bn.new(string?, base?)* + +Creates a `bn` instance. The first argument can be: + +- `nil` to creates an empty bn instance. +- A Lua number to initialize the bn instance. +- A string to initialize the bn instance. The second argument `base` specifies the base of the string, +and can take value from (compatible with Ruby OpenSSL.BN API): + - `10` or omitted, for decimal string (`"23333"`) + - `16`, for hex encoded string (`"5b25"`) + - `2`, for binary string (`"\x5b\x25"`) + - `0`, for MPI formated string (`"\x00\x00\x00\x02\x5b\x25"`) + +MPI is a format that consists of the number's length in bytes represented as a 4-byte big-endian number, and the number itself in big-endian format, where the most significant bit signals a negative number (the representation of numbers with the MSB set is prefixed with null byte). [Back to TOC](#table-of-contents) @@ -1276,6 +1423,17 @@ Returns `true` if table is an instance of `bn`. Returns `false` otherwise. [Back to TOC](#table-of-contents) +### bn.set + +**syntax**: *b, err = bn:set(number)* + +**syntax**: *b, err = bn:set(string, base?)* + +Reuse the existing bn instance and reset its value with given number or string. +Refer to [bn.new](#bnnew) for the type of arguments supported. + +[Back to TOC](#table-of-contents) + ### bn.from_binary, bn:to_binary **syntax**: *bn, err = bn.from_binary(bin)* @@ -1290,10 +1448,32 @@ Exports the BIGNUM value in binary string. used to pad leading zeros to the output to a specific length. ```lua -local b, err = require("resty.openssl.bn").from_binary(ngx.decode_base64("WyU=")) +local to_hex = require "resty.string".to_hex +local b, err = require("resty.openssl.bn").from_binary("\x5b\x25") local bin, err = b:to_binary() -ngx.say(ngx.encode_base64(bin)) --- outputs "WyU=" +ngx.say(to_hex(bin)) +-- outputs "5b25 +``` + +[Back to TOC](#table-of-contents) + +### bn.from_mpi, bn:to_mpi + +**syntax**: *bn, err = bn.from_mpi(bin)* + +**syntax**: *bin, err = bn:to_mpi()* + +Creates a `bn` instance from MPI formatted binary string. + +Exports the BIGNUM value in MPI formatted binary string. + + +```lua +local to_hex = require "resty.string".to_hex +local b, err = require("resty.openssl.bn").from_mpi("\x00\x00\x00\x02\x5b\x25") +local bin, err = b:to_mpi() +ngx.say(to_hex(bin)) +-- outputs "000000025b25 ``` [Back to TOC](#table-of-contents) @@ -1561,6 +1741,20 @@ Returns `true` if table is an instance of `cipher`. Returns `false` otherwise. [Back to TOC](#table-of-contents) +### cipher.set_buffer_size + +**syntax**: *ok = cipher.set_buffer_size(sz)* + +Resize the internal buffer size used by all cipher instance. The default buffer size is 1024 bytes. + +If you are expecting to pass input text larger than 1024 bytes at one time to `update()`, `encrypt()` +or `decrypt()`, setting the buffer to larger than the expected input size will improve performance +by let more code to be JIT-able. + +Avoid call this function at hotpath, as this re-allocate the buffer every time it's called. + +[Back to TOC](#table-of-contents) + ### cipher:get_provider_name **syntax**: *name = cipher:get_provider_name()* @@ -1918,10 +2112,13 @@ Module to interact with message authentication code (EVP_MAC). **syntax**: *h, err = mac.new(key, mac, cipher?, digest?, properties?)* -Creates a mac instance. `mac` is a case-insensitive string of digest algorithm name. +Creates a mac instance. `mac` is a case-insensitive string of MAC algorithm name. To view a list of digest algorithms implemented, use [openssl.list_mac_algorithms](#openssllist_mac_algorithms) or `openssl list -mac-algorithms`. + +At least one of `cipher` or `digest` must be specified. + `cipher` is a case-insensitive string of digest algorithm name. To view a list of digest algorithms implemented, use [openssl.list_cipher_algorithms](#openssllist_cipher_algorithms) or @@ -1988,6 +2185,16 @@ ngx.say(ngx.encode_base64(mac)) [Back to TOC](#table-of-contents) +### mac:reset + +**syntax**: *ok, err = mac:reset()* + +Reset the internal state of `mac` instance as it's just created by [mac.new](#macnew). +It calls [EVP_MAC_Init](https://www.openssl.org/docs/manmaster/man3/EVP_MAC_init.html) under +the hood. + +User must call this before reusing the same `mac` instance. + ## resty.openssl.kdf Module to interact with KDF (key derivation function). diff --git a/examples/perf/framework.lua b/examples/perf/framework.lua index eb22a2841..51bbf92af 100644 --- a/examples/perf/framework.lua +++ b/examples/perf/framework.lua @@ -64,20 +64,58 @@ local function stat(t) return v, v/#t, max end -local function test(desc, r, iter) - print("RUNNING " .. ITER .. " ITERATIONS FOR " .. desc) - local data = table.new(ITER, 0) - for i=1, ITER do - get_duration() - local ok, err = r() - data[i] = get_duration() - assert(ok, err) +local write_seperator = function() + print(string.rep("-", 64)) +end + +local no_count_iter = false + +local run_only = os.getenv("RUN_ONLY") + +local function test(desc, r, iter, expected) + if run_only and not string.match(desc, run_only) then + print("SKIP " .. desc) + return end - local sum, avg, max = stat(data) + print("RUNNING " .. ITER .. " ITERATIONS FOR " .. desc) + local sum, avg, max + local ok, err - print(string.format("FINISHED in\t%s (%d op/s)\nAVG\t%s\tMAX\t%s", hmt(sum), 1e9/avg, hmt(avg), hmt(max))) + if no_count_iter then + get_duration() + for i=1, ITER do + ok, err = r() + end + local duration = get_duration() + assert(ok, err) + sum, avg, max = duration, duration/ITER, 1/0 + else + local data = table.new(ITER, 0) + for i=1, ITER do + get_duration() + ok, err = r() + data[i] = get_duration() + assert(ok, err) + end + + sum, avg, max = stat(data) + end + + local bytes = string.match(desc, "(%d+) bytes") + if bytes then + bytes = tonumber(bytes) + bytes = bytes / 1000 * (1e9/avg) + else + bytes = 1/0 + end + print(string.format("FINISHED in\t%s (%d op/s, %.2fk bytes/s)\nAVG\t%s\tMAX\t%s", hmt(sum), 1e9/avg, bytes, hmt(avg), hmt(max))) print(string.rep("-", 64)) + + if expected ~= nil then + assert(expected == ok, "expected " .. expected .. "(" .. (#expected or 0) .. " bytes)" .. + ", but got " .. ok .. "(" .. (#ok or 0) .. " bytes)") + end end local function set_iteration(i) @@ -85,9 +123,14 @@ local function set_iteration(i) end print("LOADING TEST FROM " .. arg[0]) -print(string.rep("=", 64)) + +write_seperator() return { test = test, set_iteration = set_iteration, + write_seperator = write_seperator, + set_no_count_iter = function(s) + no_count_iter = s + end, } diff --git a/examples/perf/test_cipher.lua b/examples/perf/test_cipher.lua index fc2245665..2f167caa4 100644 --- a/examples/perf/test_cipher.lua +++ b/examples/perf/test_cipher.lua @@ -3,6 +3,7 @@ package.path = path .. "/?.lua;" .. package.path local test = require "framework".test local set_iteration = require "framework".set_iteration +local write_seperator = require "framework".write_seperator local cipher = require "resty.openssl.cipher" local version = require("resty.openssl.version") @@ -46,4 +47,6 @@ for _, t in ipairs({"aes-256-cbc", "aes-256-gcm", "chacha20-poly1305"}) do end ::continue:: end + + write_seperator() end diff --git a/examples/perf/test_other_libs.lua b/examples/perf/test_other_libs.lua new file mode 100644 index 000000000..e20c4c3f5 --- /dev/null +++ b/examples/perf/test_other_libs.lua @@ -0,0 +1,433 @@ +local path = debug.getinfo(1, "S").source:sub(2):match("(.*/)") +package.path = path .. "/?.lua;" .. package.path + +local test = require "framework".test +local set_iteration = require "framework".set_iteration +local write_seperator = require "framework".write_seperator +local cipher = require "resty.openssl.cipher" +local digest = require "resty.openssl.digest" +local hmac = require "resty.openssl.hmac" +local pkey = require "resty.openssl.pkey" +local version = require "resty.openssl.version" +local rand = require "resty.openssl.rand" +local kdf = require "resty.openssl.kdf" +local aes = require "resty.aes" +local resty_rsa = require "resty.rsa" +local to_hex = require "resty.string".to_hex + +-- ensure best performance +require "framework".set_no_count_iter(true) + +local luaossl +do + local pok, perr, err = pcall(require, "_openssl") + if pok then + luaossl = perr + end +end + +local lua_openssl +do + -- move openssl.so to lua-openssl.so to avoid conflict with luaossl + local pok, perr, err = pcall(require, "lua-openssl") + if pok then + lua_openssl = perr + end +end + +local lua_pack +do + local pok, perr, err = pcall(require, "lua_pack") + if pok then + lua_pack = perr + end +end + +local v = require "jit.dump" +v.on(nil, "/tmp/a.out") + +------------- bn +do + set_iteration(1000000) + + local binary_input = rand.bytes(24) + local bn = require "resty.openssl.bn" + local hex_input = assert(bn.from_binary(binary_input)):to_hex() + + test("lua-resty-openssl bn unpack parse binary", function() + return bn.new(hex_input, 16) + end) + + local bni = bn.new() + test("lua-resty-openssl bn unpack parse binary reused struct", function() + return bni:set(hex_input, 16) + end) + + if luaossl then + local luaossl_bn = require "_openssl.bignum" + local hex_input = "0X" .. hex_input + + test("luaossl bn unpack parse binary", function() + return luaossl_bn.new(hex_input) + end) + end + + if lua_openssl then + local hex_input = "X" .. hex_input + test("lua-openssl bn unpack parse binary", function() + return lua_openssl.bn.number(hex_input) + end) + end + + if lua_pack then + test("lua_pack bn unpack 6 int", function() + return lua_pack.unpack(binary_input, ">6I") + end) + end +end + +------------- cipher +do + write_seperator() + + local key = rand.bytes(32) + local iv = rand.bytes(16) + local data = string.rep("1", 4096) + + set_iteration(100000) + + for _, t in ipairs({"aes-256-cbc", "aes-256-gcm"}) do + for _, op in ipairs({"encrypt", "decrypt"}) do + + local c = assert(cipher.new(t)) + cipher.set_buffer_size(#data + 64) -- add room for decrypt + + local _iv = iv + if t == "aes-256-gcm" then + _iv = string.rep("0", 12) + end + + local aes_default + if t == "aes-256-cbc" then + aes_default = aes:new(key, nil, aes.cipher(256, "cbc"), {iv = _iv}) + else + aes_default = aes:new(key, nil, aes.cipher(256, "gcm"), {iv = _iv}) + end + + local luaossl_aes + if luaossl then + local luaossl_cipher = require "_openssl.cipher" + luaossl_aes = luaossl_cipher.new(t) + end + + local ciphertext = assert(c:encrypt(key, _iv, data, false)) + + if op == "encrypt" then + -- assert(c:init(key, _iv, {is_encrypt = true })) + -- assert(c:encrypt(key, _iv, data, false)) + test("lua-resty-openssl encrypt with " .. t .. " on " .. #data .. " bytes", function() + return c:encrypt(key, _iv, data, false) + -- return c:final(data) + end, nil, ciphertext) + + test("lua-resty-strings encrypt with " .. t .. " on " .. #data .. " bytes", function() + local r = aes_default:encrypt(data) + if t == "aes-256-gcm" then + return r[1] + end + return r + end, nil, ciphertext) + + if luaossl then + test("luaossl encrypt with " .. t .. " on " .. #data .. " bytes", function() + return luaossl_aes:encrypt(key, _iv):final(data) + end, nil, ciphertext) + end + + if lua_openssl then + local evp_cipher = lua_openssl.cipher.get(t) + test("lua_openssl encrypt with " .. t .. " on " .. #data .. " bytes", function() + return evp_cipher:encrypt(data, key, _iv) + end, nil, ciphertext) + end + + + else + + local tag + if t == "aes-256-gcm" then + tag = assert(c:get_aead_tag()) + end + -- assert(c:init(key, _iv)) + test("lua-resty-openssl decrypt with " .. t .. " on " .. #ciphertext .. " bytes", function() + -- if tag then + -- c:set_aead_tag(tag) + --end + --return c:final(ciphertext) + return c:decrypt(key, _iv, ciphertext, false, nil, tag) + end, nil, data) + + + test("lua-resty-strings decrypt with " .. t .. " on " .. #ciphertext .. " bytes", function() + return aes_default:decrypt(ciphertext, tag) + end, nil, data) + + if luaossl then + --local luaossl_cipher = require "openssl.cipher" + --local luaossl_aes2 = luaossl_cipher.new(t) + + test("luaossl decrypt with " .. t .. " on " .. #ciphertext .. " bytes", function() + luaossl_aes:decrypt(key, _iv) + if t == "aes-256-gcm" then + luaossl_aes:setTag(tag) + end + return luaossl_aes:final(ciphertext) + end, nil, data) + end + + + if lua_openssl then + local evp = lua_openssl.cipher.get(t) + + local d = evp:decrypt_new(key, _iv) + test("lua_openssl decrypt with " .. t .. " on " .. #ciphertext .. " bytes", function() + d:ctrl(lua_openssl.cipher.EVP_CTRL_GCM_SET_IVLEN, #_iv) + d:init(key, _iv) + d:padding(false) + + local r = d:update(ciphertext) + if t == "aes-256-gcm" then + assert(d:ctrl(lua_openssl.cipher.EVP_CTRL_GCM_SET_TAG, tag)) + end + return r .. d:final() + end) -- has extra padding: , nil, data) + end + end + ::continue:: + end + + write_seperator() + end +end + +------------- digest +do + write_seperator() + + local data = string.rep("1", 4096) + + for _, t in ipairs({"sha256", "md5"}) do + + local d = digest.new(t) + + local expected = d:final(data) + + test("lua-resty-openssl " .. t .. " on " .. #data .. " bytes", function() + d:reset() + return d:final(data) + end, nil, expected) + + local h = require ("resty." .. t) + local hh = h:new() + + test("lua-resty-strings " .. t .. " on " .. #data .. " bytes", function() + hh:reset() + hh:update(data) + return hh:final() + end, nil, expected) + + if luaossl then + local _digest = require "_openssl.digest" + test("luaossl " .. t .. " on " .. #data .. " bytes", function() + local hh = _digest.new(t) + return hh:final(data) + end, nil, expected) + end + + if lua_openssl then + local hh = lua_openssl.digest.get(t) + test("lua_openssl " .. t .. " on " .. #data .. " bytes", function() + return hh:digest(data) + end, nil, expected) + end + + if t == "md5" then + test("ngx.md5_bin on " .. #data .. " bytes", function() + return ngx.md5_bin(data) + end, nil, expected) + end + end + +end + +------------- hmac +do + write_seperator() + + local data = string.rep("1", 4096) + local key = rand.bytes(32) + + local d = hmac.new(key, "sha256") + + local expected = d:final(data) + + test("lua-resty-openssl hmac sha256 on " .. #data .. " bytes", function() + d:reset() + return d:final(data) + end, nil, expected) + + if version.OPENSSL_3X then + local mac = require "resty.openssl.mac" + local m = mac.new(key, "HMAC", nil, "sha256") + test("lua-resty-openssl hmac sha256 new API on " .. #data .. " bytes", function() + m:reset() + return m:final(data) + end, nil, expected) + end + + if luaossl then + local _hmac = require "_openssl.hmac" + test("luaossl hmac sha256 " .. #data .. " bytes", function() + local hh = _hmac.new(key, "sha256") + return hh:final(data) + end, nil, expected) + end + + if lua_openssl then + local hh = lua_openssl.hmac + test("lua_openssl hmac sha256 on " .. #data .. " bytes", function() + return hh.hmac("sha256", data, key) + end, nil, to_hex(expected)) + + if version.OPENSSL_3X then + local mm = lua_openssl.mac + test("lua_openssl hmac sha256 new API on " .. #data .. " bytes", function() + return mm.mac("sha256", data, key) + end, nil, to_hex(expected)) + end + end +end + +------------- pkey +do + write_seperator() + + local key = pkey.new({ type = "RSA", bits = 4096 }) + local data = string.rep("1", 200) + local rsa_encrypted = assert(key:encrypt(data, pkey.PADDINGS.RSA_PKCS1_PADDING)) + + set_iteration(1000) + + for _, op in ipairs({"encrypt", "decrypt"}) do + local _data = data + if op == "decrypt" then + _data = rsa_encrypted + end + + local f = key[op] + test("lua-resty-openssl RSA " .. op .. " on " .. #data .. " bytes", function() + return f(key, _data) + end) + + if not version.OPENSSL_3X then + local pub = resty_rsa:new({ public_key = key:to_PEM("public"), padding = resty_rsa.PADDING.RSA_PKCS1_PADDING }) + local priv = resty_rsa:new({ private_key = key:to_PEM("private"), padding = resty_rsa.PADDING.RSA_PKCS1_PADDING }) + + local _key = pub + if op == "decrypt" then + _key = priv + end + + local f = _key[op] + test("lua-resty-rsa RSA " .. op .." on " .. #data .. " bytes", function() + return f(_key, _data) + end) + end + + if luaossl then + local _key = require "_openssl.pkey".new(key:to_PEM("private")) + local f = _key[op] + test("luaossl RSA " .. op .." on " .. #data .. " bytes", function() + return f(_key, _data) + end) + end + + + if lua_openssl then + local _key = lua_openssl.pkey.read(key:to_PEM("private"), true) + local f = _key[op] + test("lua_openssl RSA " .. op .." on " .. #data .. " bytes", function() + return f(_key, _data) + end) + end + end + +end + +------------- kdf +do + write_seperator() + + local kdf_out_size = 64 + local kdf_pass = "1234567" + local kdf_md = "md5" + local kdf_salt = rand.bytes(16) + + set_iteration(500) + + local kdf_opts = { + type = kdf.PBKDF2, + outlen = kdf_out_size, + pass = kdf_pass, + md = kdf_md, + salt = kdf_salt, + pbkdf2_iter = 1000, + } + local expected = assert(kdf.derive(kdf_opts)) + + test("lua-resty-openssl kdf pbkdf2 outputs " .. kdf_out_size .. " bytes", function() + return kdf.derive(kdf_opts) + end) + + if version.OPENSSL_3X then + local kdfi = kdf.new("pbkdf2") + kdf_opts = { + pass = kdf_pass, + iter = 1000, + digest = kdf_md, + salt = kdf_salt, + } + test("lua-resty-openssl kdf new API pbkdf2 outputs " .. kdf_out_size .. " bytes", function() + return kdfi:derive(kdf_out_size, kdf_opts) + end, nil, expected) + end + + if luaossl then + local _kdf = require "_openssl.kdf" + local kdf_opts = { + type = "PBKDF2", + outlen = kdf_out_size, + pass = kdf_pass, + md = kdf_md, + salt = kdf_salt, + iter = 1000, + } + test("luaossl kdf pbkf2 outputs " .. kdf_out_size .. " bytes", function() + return _kdf.derive(kdf_opts) + end, nil, expected) + end + + + if lua_openssl and version.OPENSSL_3X then + local _kdf = lua_openssl.kdf.fetch('PBKDF2') + local kdf_opts = { + { name = "pass", data = kdf_pass }, + { name = "iter", data = 1000 }, + { name = "digest", data = kdf_md }, + { name = "salt", data = kdf_salt }, + } + test("lua_openssl kdf pbkf2 outputs " .. kdf_out_size .. " bytes", function() + return _kdf:derive(kdf_opts, kdf_out_size) + end, nil, expected) + end +end diff --git a/examples/perf/test_pkey_asymm.lua b/examples/perf/test_pkey_asymm.lua index c153e7c4f..e4e405451 100644 --- a/examples/perf/test_pkey_asymm.lua +++ b/examples/perf/test_pkey_asymm.lua @@ -3,6 +3,7 @@ package.path = path .. "/?.lua;" .. package.path local test = require "framework".test local set_iteration = require "framework".set_iteration +local write_seperator = require "framework".write_seperator local pkey = require "resty.openssl.pkey" local version = require("resty.openssl.version") local data = string.rep("=", 200) @@ -26,6 +27,7 @@ for _, op in ipairs({"encrypt", "decrypt"}) do end end +write_seperator() for _, t in ipairs({"RSA", "EC", "Ed25519", "Ed448"}) do for _, op in ipairs({"sign", "verify"}) do @@ -61,4 +63,6 @@ for _, t in ipairs({"RSA", "EC", "Ed25519", "Ed448"}) do end ::continue:: end + + write_seperator() end diff --git a/examples/perf/test_pkey_codec.lua b/examples/perf/test_pkey_codec.lua index 973b8bb59..15f57f32d 100644 --- a/examples/perf/test_pkey_codec.lua +++ b/examples/perf/test_pkey_codec.lua @@ -2,11 +2,12 @@ local path = debug.getinfo(1, "S").source:sub(2):match("(.*/)") package.path = path .. "/?.lua;" .. package.path local test = require "framework".test +local write_seperator = require "framework".write_seperator local pkey = require "resty.openssl.pkey" local example_pkey = assert(pkey.new()) -for _, op in ipairs({"load", "export"}) do - for _, t in ipairs({"PEM", "DER", "JWK"}) do +for _, t in ipairs({"PEM", "DER", "JWK"}) do + for _, op in ipairs({"load", "export"}) do for _, p in ipairs({"public", "private"}) do if op == "load" then @@ -30,4 +31,6 @@ for _, op in ipairs({"load", "export"}) do end end + + write_seperator() end diff --git a/examples/perf/test_x509_codec.lua b/examples/perf/test_x509_codec.lua index abc74df52..2d5b5a591 100644 --- a/examples/perf/test_x509_codec.lua +++ b/examples/perf/test_x509_codec.lua @@ -2,12 +2,13 @@ local path = debug.getinfo(1, "S").source:sub(2):match("(.*/)") package.path = path .. "/?.lua;" .. package.path local test = require "framework".test +local write_seperator = require "framework".write_seperator local x509 = require "resty.openssl.x509" local cert = assert(io.open(path .. "../../t/fixtures/Github.pem")):read("*a") local example_x509 = assert(x509.new(cert)) -for _, op in ipairs({"load", "export"}) do - for _, t in ipairs({"PEM", "DER"}) do +for _, t in ipairs({"PEM", "DER"}) do + for _, op in ipairs({"load", "export"}) do if op == "load" then local txt = assert(example_x509:tostring(t)) test("load " .. t .. " x509", function() @@ -20,4 +21,6 @@ for _, op in ipairs({"load", "export"}) do end) end end + + write_seperator() end diff --git a/lib/resty/openssl.lua b/lib/resty/openssl.lua index 7bd9dcb55..fba8ae6b1 100644 --- a/lib/resty/openssl.lua +++ b/lib/resty/openssl.lua @@ -24,31 +24,9 @@ try_require_modules() local _M = { - _VERSION = '1.0.2', + _VERSION = '1.2.0', } -local libcrypto_name -local lib_patterns = { - "%s", "%s.so.3", "%s.so.1.1", "%s.so.1.0" -} - -function _M.load_library() - for _, pattern in ipairs(lib_patterns) do - -- true: load to global namespae - local pok, _ = pcall(ffi.load, string.format(pattern, "crypto"), true) - if pok then - libcrypto_name = string.format(pattern, "crypto") - ffi.load(string.format(pattern, "ssl"), true) - - try_require_modules() - - return libcrypto_name - end - end - - return false, "unable to load crypto library" -end - function _M.load_modules() _M.bn = require("resty.openssl.bn") _M.cipher = require("resty.openssl.cipher") @@ -348,7 +326,7 @@ local function list_legacy(typ, get_nid_cf) return ret end -local function list_provided(typ) +local function list_provided(typ, hide_provider) local typ_lower = string.lower(typ:sub(5)) -- cut off EVP_ local typ_ptr = typ .. "*" require ("resty.openssl.include.evp." .. typ_lower) @@ -360,9 +338,13 @@ local function list_provided(typ) function(elem, _) elem = ffi_cast(typ_ptr, elem) local name = ffi_str(C[typ .. "_get0_name"](elem)) - -- alternate names are ignored, retrieve use TYPE_names_do_all - local prov = ffi_str(C.OSSL_PROVIDER_get0_name(C[typ .. "_get0_provider"](elem))) - table.insert(ret, name .. " @ " .. prov) + if hide_provider then + table.insert(ret, name) + else + -- alternate names are ignored, retrieve use TYPE_names_do_all + local prov = ffi_str(C.OSSL_PROVIDER_get0_name(C[typ .. "_get0_provider"](elem))) + table.insert(ret, name .. " @ " .. prov) + end end) C[typ .. "_do_all_provided"](ctx_lib.get_libctx(), fn, nil) @@ -372,50 +354,40 @@ local function list_provided(typ) return ret end -function _M.list_cipher_algorithms() +function _M.list_cipher_algorithms(hide_provider) require "resty.openssl.include.evp.cipher" - local ret = list_legacy("EVP_CIPHER", - OPENSSL_3X and C.EVP_CIPHER_get_nid or C.EVP_CIPHER_nid) if OPENSSL_3X then - local ret_provided = list_provided("EVP_CIPHER") - for _, r in ipairs(ret_provided) do - table.insert(ret, r) - end + return list_provided("EVP_CIPHER", hide_provider) + else + return list_legacy("EVP_CIPHER", C.EVP_CIPHER_nid) end - - return ret end -function _M.list_digest_algorithms() +function _M.list_digest_algorithms(hide_provider) require "resty.openssl.include.evp.md" - local ret = list_legacy("EVP_MD", - OPENSSL_3X and C.EVP_MD_get_type or C.EVP_MD_type) if OPENSSL_3X then - local ret_provided = list_provided("EVP_MD") - for _, r in ipairs(ret_provided) do - table.insert(ret, r) - end + return list_provided("EVP_MD", hide_provider) + else + return list_legacy("EVP_MD", C.EVP_MD_type) end - - return ret end -function _M.list_mac_algorithms() +function _M.list_mac_algorithms(hide_provider) if not OPENSSL_3X then return nil, "openssl.list_mac_algorithms is only supported from OpenSSL 3.0" end - return list_provided("EVP_MAC") + return list_provided("EVP_MAC", hide_provider) end -function _M.list_kdf_algorithms() +function _M.list_kdf_algorithms(hide_provider) if not OPENSSL_3X then return nil, "openssl.list_kdf_algorithms is only supported from OpenSSL 3.0" end - return list_provided("EVP_KDF") + return list_provided("EVP_KDF", hide_provider) end local valid_ssl_protocols = { diff --git a/lib/resty/openssl/auxiliary/compat.lua b/lib/resty/openssl/auxiliary/compat.lua new file mode 100644 index 000000000..10dd36df4 --- /dev/null +++ b/lib/resty/openssl/auxiliary/compat.lua @@ -0,0 +1,84 @@ +local nkeys + +do + local pok, perr = pcall(require, "table.nkeys") + if pok then + nkeys = perr + else + nkeys = function(tbl) + local cnt = 0 + for _ in pairs(tbl) do + cnt = cnt + 1 + end + return cnt + end + end +end + +local noop = function() end + +local log_warn, log_debug +local encode_base64url, decode_base64url + +if ngx then + log_warn = function(...) + ngx.log(ngx.WARN, ...) + end + + log_debug = function(...) + ngx.log(ngx.DEBUG, ...) + end + + local b64 = require("ngx.base64") + encode_base64url = b64.encode_base64url + decode_base64url = b64.decode_base64url + +else + log_warn = noop + log_debug = noop + + local pok, basexx = pcall(require, "basexx") + if pok then + encode_base64url = basexx.to_url64 + decode_base64url = basexx.from_url64 + else + encode_base64url = function() + error("no base64 library is found, needs either ngx.base64 or basexx") + end + decode_base64url = encode_base64url + end + +end + +local json +do + local pok, perr = pcall(require, "cjson.safe") + if pok then + json = perr + else + local pok, perr = pcall(require, "dkjson") + if pok then + json = perr + end + end + + if not json then + json = setmetatable({}, { + __index = function() + return function() + error("no JSON library is found, needs either cjson or dkjson") + end + end, + }) + end +end + + +return { + nkeys = nkeys, + log_warn = log_warn, + log_debug = log_debug, + encode_base64url = encode_base64url, + decode_base64url = decode_base64url, + json = json, +} \ No newline at end of file diff --git a/lib/resty/openssl/auxiliary/jwk.lua b/lib/resty/openssl/auxiliary/jwk.lua index 3738e99e0..8d81ebff3 100644 --- a/lib/resty/openssl/auxiliary/jwk.lua +++ b/lib/resty/openssl/auxiliary/jwk.lua @@ -2,8 +2,6 @@ local ffi = require "ffi" local C = ffi.C -local cjson = require("cjson.safe") -local b64 = require("ngx.base64") local evp_macro = require "resty.openssl.include.evp" local rsa_lib = require "resty.openssl.rsa" @@ -11,6 +9,9 @@ local ec_lib = require "resty.openssl.ec" local ecx_lib = require "resty.openssl.ecx" local bn_lib = require "resty.openssl.bn" local digest_lib = require "resty.openssl.digest" +local encode_base64url = require "resty.openssl.auxiliary.compat".encode_base64url +local decode_base64url = require "resty.openssl.auxiliary.compat".decode_base64url +local json = require "resty.openssl.auxiliary.compat".json local _M = {} @@ -27,7 +28,7 @@ local function load_jwk_rsa(tbl) for i, k in ipairs(rsa_jwk_params) do local v = tbl[k] if v then - v = b64.decode_base64url(v) + v = decode_base64url(v) if not v then return nil, "cannot decode parameter \"" .. k .. "\" from base64 " .. tbl[k] end @@ -86,7 +87,7 @@ local function load_jwk_ec(tbl) for _, k in ipairs(ec_jwk_params) do local v = tbl[k] if v then - v = b64.decode_base64url(v) + v = decode_base64url(v) if not v then return nil, "cannot decode parameter \"" .. k .. "\" from base64 " .. tbl[k] end @@ -122,9 +123,9 @@ end local function load_jwk_okp(key_type, tbl) local params = {} if tbl["d"] then - params.private = b64.decode_base64url(tbl["d"]) + params.private = decode_base64url(tbl["d"]) elseif tbl["x"] then - params.public = b64.decode_base64url(tbl["x"]) + params.public = decode_base64url(tbl["x"]) else return nil, "at least \"x\" or \"d\" parameter is required" end @@ -141,7 +142,7 @@ for k, v in pairs(evp_macro.ecx_curves) do end function _M.load_jwk(txt) - local tbl, err = cjson.decode(txt) + local tbl, err = json.decode(txt) if err then return nil, "error decoding JSON from JWK: " .. err elseif type(tbl) ~= "table" then @@ -220,7 +221,7 @@ function _M.dump_jwk(pkey, is_priv) } for i, p in ipairs(param_keys) do local v = params[rsa_openssl_params[i]]:to_binary() - jwk[p] = b64.encode_base64url(v) + jwk[p] = encode_base64url(v) end elseif pkey.key_type == evp_macro.EVP_PKEY_EC then local params, err = pkey:get_parameters() @@ -230,11 +231,11 @@ function _M.dump_jwk(pkey, is_priv) jwk = { kty = "EC", crv = ec_curves_reverse[params.group], - x = b64.encode_base64url(params.x:to_binary()), - y = b64.encode_base64url(params.y:to_binary()), + x = encode_base64url(params.x:to_binary()), + y = encode_base64url(params.y:to_binary()), } if is_priv then - jwk.d = b64.encode_base64url(params.private:to_binary()) + jwk.d = encode_base64url(params.private:to_binary()) end elseif ecx_curves_reverse[pkey.key_type] then local params, err = pkey:get_parameters() @@ -244,8 +245,8 @@ function _M.dump_jwk(pkey, is_priv) jwk = { kty = "OKP", crv = ecx_curves_reverse[pkey.key_type], - d = b64.encode_base64url(params.private), - x = b64.encode_base64url(params.public), + d = encode_base64url(params.private), + x = encode_base64url(params.public), } else return nil, "jwk.dump_jwk: not implemented for this key type" @@ -257,9 +258,9 @@ function _M.dump_jwk(pkey, is_priv) if err then return nil, "jwk.dump_jwk: failed to calculate digest for key" end - jwk.kid = b64.encode_base64url(d) + jwk.kid = encode_base64url(d) - return cjson.encode(jwk) + return json.encode(jwk) end return _M diff --git a/lib/resty/openssl/bn.lua b/lib/resty/openssl/bn.lua index 3c4fce440..4c66f1ae0 100644 --- a/lib/resty/openssl/bn.lua +++ b/lib/resty/openssl/bn.lua @@ -9,7 +9,6 @@ require "resty.openssl.include.bn" local crypto_macro = require("resty.openssl.include.crypto") local ctypes = require "resty.openssl.auxiliary.ctypes" local format_error = require("resty.openssl.err").format_error -local OPENSSL_3X = require("resty.openssl.version").OPENSSL_3X local _M = {} local mt = {__index = _M} @@ -17,16 +16,73 @@ local mt = {__index = _M} local bn_ptr_ct = ffi.typeof('BIGNUM*') local bn_ptrptr_ct = ffi.typeof('BIGNUM*[1]') -function _M.new(bn) +local function set_binary(ctx, s) + local ctx = C.BN_bin2bn(s, #s, ctx) + if ctx == nil then + return nil, format_error("set_binary") + end + return ctx +end + +local function set_mpi(ctx, s) + local ctx = C.BN_mpi2bn(s, #s, ctx) + if ctx == nil then + return nil, format_error("set_mpi") + end + return ctx +end + +local function set_hex(ctx, s) + local p = ffi_new(bn_ptrptr_ct) + p[0] = ctx + + if C.BN_hex2bn(p, s) == 0 then + return nil, format_error("set_hex") + end + return p[0] +end + +local function set_dec(ctx, s) + local p = ffi_new(bn_ptrptr_ct) + p[0] = ctx + + if C.BN_dec2bn(p, s) == 0 then + return nil, format_error("set_dec") + end + return p[0] +end + +local function set_bn(ctx, s, base) + if type(s) == 'number' then + if C.BN_set_word(ctx, s) ~= 1 then + return nil, format_error("set_bn") + end + elseif type(s) == 'string' then + if not base or base == 10 then + return set_dec(ctx, s) + elseif base == 16 then + return set_hex(ctx, s) + elseif base == 2 then + return set_binary(ctx, s) + elseif base == 0 then + ctx = set_mpi(ctx, s) + else + return nil, "set_bn: unsupported base: " .. base + end + elseif s then + return nil, "set_bn: expect nil, a number or a string at #1" + end + + return ctx +end + +function _M.new(some, base) local ctx = C.BN_new() ffi_gc(ctx, C.BN_free) - if type(bn) == 'number' then - if C.BN_set_word(ctx, bn) ~= 1 then - return nil, format_error("bn.new") - end - elseif bn then - return nil, "bn.new: expect nil or a number at #1" + local ctx, err = set_bn(ctx, some, base) + if err then + return nil, "bn.new: " .. err end return setmetatable( { ctx = ctx }, mt), nil @@ -50,6 +106,19 @@ function _M.dup(ctx) return self end +function _M:set(some, base) + if not some then + return nil, "expect a number or a string at #1" + end + + local _, err = set_bn(self.ctx, some, base) + if err then + return nil, "bn:set: " .. err + end + + return self +end + function _M:to_binary(pad) if pad then if type(pad) ~= "number" then @@ -80,17 +149,22 @@ function _M:to_binary(pad) return ffi_str(buf, sz) end -function _M.from_binary(s) - if type(s) ~= "string" then - return nil, "bn.from_binary: expect a string at #1" +function _M:to_mpi(no_header) + local length = C.BN_bn2mpi(self.ctx, nil) + if length <= 0 then + return nil, format_error("bn:to_mpi") end - local ctx = C.BN_bin2bn(s, #s, nil) - if ctx == nil then - return nil, format_error("bn.from_binary") + local buf = ctypes.uchar_array(length) + + local sz = C.BN_bn2mpi(self.ctx, buf) + if sz <= 0 then + return nil, format_error("bn:to_mpi") end - ffi_gc(ctx, C.BN_free) - return setmetatable( { ctx = ctx }, mt), nil + + local ret = ffi_str(buf, sz) + + return no_header and ret:sub(4) or ret end function _M:to_hex() @@ -103,21 +177,6 @@ function _M:to_hex() return s end -function _M.from_hex(s) - if type(s) ~= "string" then - return nil, "bn.from_hex: expect a string at #1" - end - - local p = ffi_new(bn_ptrptr_ct) - - if C.BN_hex2bn(p, s) == 0 then - return nil, format_error("bn.from_hex") - end - local ctx = p[0] - ffi_gc(ctx, C.BN_free) - return setmetatable( { ctx = ctx }, mt), nil -end - function _M:to_dec() local buf = C.BN_bn2dec(self.ctx) if buf == nil then @@ -129,26 +188,35 @@ function _M:to_dec() end mt.__tostring = _M.to_dec -function _M.from_dec(s) - if type(s) ~= "string" then - return nil, "bn.from_dec: expect a string at #1" - end - - local p = ffi_new(bn_ptrptr_ct) - - if C.BN_dec2bn(p, s) == 0 then - return nil, format_error("bn.from_dec") - end - local ctx = p[0] - ffi_gc(ctx, C.BN_free) - return setmetatable( { ctx = ctx }, mt), nil -end - function _M:to_number() return tonumber(C.BN_get_word(self.ctx)) end _M.tonumber = _M.to_number +local from_funcs = { + binary = set_binary, + mpi = set_mpi, + hex = set_hex, + dec = set_dec, +} + +for typ, func in pairs(from_funcs) do + local sig = "from_" .. typ + _M[sig] = function(s) + if type(s) ~= "string" then + return nil, "bn." .. sig .. ": expect a string at #1" + end + + local ctx, err = func(nil, s) + if not ctx then + return nil, "bn." .. sig .. ": " .. err + end + + ffi_gc(ctx, C.BN_free) + return setmetatable( { ctx = ctx }, mt), nil + end +end + function _M.generate_prime(bits, safe) local ctx = C.BN_new() ffi_gc(ctx, C.BN_free) @@ -373,12 +441,7 @@ function _M:is_prime(nchecks) end -- if nchecks is not defined, set to BN_prime_checks: -- select number of iterations based on the size of the number - local code - if OPENSSL_3X then - code = C.BN_check_prime(self.ctx, bn_ctx_tmp, nil) - else - code = C.BN_is_prime_ex(self.ctx, nchecks or 0, bn_ctx_tmp, nil) - end + local code = C.BN_is_prime_ex(self.ctx, nchecks or 0, bn_ctx_tmp, nil) if code == -1 then return nil, format_error("bn.is_prime") end diff --git a/lib/resty/openssl/cipher.lua b/lib/resty/openssl/cipher.lua index f247ed9a6..8e7e60741 100644 --- a/lib/resty/openssl/cipher.lua +++ b/lib/resty/openssl/cipher.lua @@ -10,11 +10,11 @@ local ctypes = require "resty.openssl.auxiliary.ctypes" local ctx_lib = require "resty.openssl.ctx" local format_error = require("resty.openssl.err").format_error local OPENSSL_3X = require("resty.openssl.version").OPENSSL_3X +local log_warn = require "resty.openssl.auxiliary.compat".log_warn local uchar_array = ctypes.uchar_array local void_ptr = ctypes.void_ptr local ptr_of_int = ctypes.ptr_of_int -local uchar_ptr = ctypes.uchar_ptr local _M = {} local mt = {__index = _M} @@ -23,7 +23,8 @@ local cipher_ctx_ptr_ct = ffi.typeof('EVP_CIPHER_CTX*') local out_length = ptr_of_int() -- EVP_MAX_BLOCK_LENGTH is 32, we give it a 64 to be future proof -local out_buffer = ctypes.uchar_array(1024 + 64) +local out_buffer_size = 1024 +local out_buffer = ctypes.uchar_array(out_buffer_size + 64) function _M.new(typ, properties) if not typ then @@ -69,6 +70,15 @@ function _M.istype(l) return l and l.ctx and ffi.istype(cipher_ctx_ptr_ct, l.ctx) end +function _M.set_buffer_size(sz) + if out_buffer_size ~= sz then + out_buffer_size = sz + out_buffer = ctypes.uchar_array(sz + 64) + end + + return true +end + function _M:get_provider_name() if not OPENSSL_3X then return false, "cipher:get_provider_name is not supported" @@ -195,49 +205,54 @@ function _M:set_aead_tag(tag) return true end +local update_buffer = {} function _M:update(...) if not self.initialized then return nil, "cipher:update: cipher not initalized, call cipher:init first" end - local ret = {} + table.clear(update_buffer) + local _out_buffer = out_buffer for i, s in ipairs({...}) do local inl = #s - if inl > 1024 then - s = ffi_cast(uchar_ptr, s) - for i=0, inl-1, 1024 do - local chunk_size = 1024 - if inl - i < 1024 then - chunk_size = inl - i - end - if C.EVP_CipherUpdate(self.ctx, out_buffer, out_length, s+i, chunk_size) ~= 1 then - return nil, format_error("cipher:update") - end - table.insert(ret, ffi_str(out_buffer, out_length[0])) - end - else - if C.EVP_CipherUpdate(self.ctx, out_buffer, out_length, s, inl) ~= 1 then - return nil, format_error("cipher:update") - end - table.insert(ret, ffi_str(out_buffer, out_length[0])) + if inl > out_buffer_size and _out_buffer == out_buffer then + -- create a larger buffer than the default one + _out_buffer = ctypes.uchar_array(inl + 64) end + if C.EVP_CipherUpdate(self.ctx, _out_buffer, out_length, s, inl) ~= 1 then + return nil, format_error("cipher:update") + end + table.insert(update_buffer, ffi_str(_out_buffer, out_length[0])) end - return table.concat(ret, "") + return table.concat(update_buffer, "") end function _M:final(s) - local ret, err - if s then - ret, err = self:update(s) - if err then - return nil, err - end + if not self.initialized then + return nil, "cipher:update: cipher not initalized, call cipher:init first" end - if C.EVP_CipherFinal_ex(self.ctx, out_buffer, out_length) ~= 1 then + + out_length[0] = 0 + local offset = 0 -- advance the offset if we have update buffer + local _out_buffer = out_buffer + if s then + local inl = #s + if inl > out_buffer_size then + -- create a larger buffer than the default one + _out_buffer = ctypes.uchar_array(inl + 64) + end + + if C.EVP_CipherUpdate(self.ctx, _out_buffer, out_length, s, inl) ~= 1 then + return nil, format_error("cipher:final") + end + offset = out_length[0] + end + + if C.EVP_CipherFinal_ex(self.ctx, _out_buffer + offset, out_length) ~= 1 then return nil, format_error("cipher:final: EVP_CipherFinal_ex") end - local final_ret = ffi_str(out_buffer, out_length[0]) - return ret and (ret .. final_ret) or final_ret + + return ffi_str(_out_buffer, out_length[0] + offset) end @@ -257,10 +272,10 @@ function _M:derive(key, salt, count, md, md_properties) if salt then if #salt > 8 then - ngx.log(ngx.WARN, "cipher:derive: salt is too long, truncate salt to 8 bytes") + log_warn("cipher:derive: salt is too long, truncate salt to 8 bytes") salt = salt:sub(0, 8) elseif #salt < 8 then - ngx.log(ngx.WARN, "cipher:derive: salt is too short, padding with zero bytes to length") + log_warn("cipher:derive: salt is too short, padding with zero bytes to length") salt = salt .. string.rep('\000', 8 - #salt) end end diff --git a/lib/resty/openssl/ctx.lua b/lib/resty/openssl/ctx.lua index eaec39627..2659d2bf5 100644 --- a/lib/resty/openssl/ctx.lua +++ b/lib/resty/openssl/ctx.lua @@ -26,7 +26,7 @@ local function new(request_context_only, conf_file) return false, format_error("ctx.new") end - if request_context_only then + if request_context_only and ngx then ngx.ctx.ossl_lib_ctx = ctx else ossl_lib_ctx = ctx @@ -40,7 +40,7 @@ local function free(request_context_only) return false, "ctx is only supported from OpenSSL 3.0" end - if request_context_only then + if request_context_only and ngx then ngx.ctx.ossl_lib_ctx = nil else ossl_lib_ctx = nil diff --git a/lib/resty/openssl/err.lua b/lib/resty/openssl/err.lua index a047a7c01..61dad9b6d 100644 --- a/lib/resty/openssl/err.lua +++ b/lib/resty/openssl/err.lua @@ -5,27 +5,70 @@ local ffi_sizeof = ffi.sizeof local ctypes = require "resty.openssl.auxiliary.ctypes" require "resty.openssl.include.err" +local OPENSSL_3X = require("resty.openssl.version").OPENSSL_3X local constchar_ptrptr = ffi.typeof("const char*[1]") -local buf = ffi.new('char[256]') +local last_err_code = 0 + +local function get_last_error_code() + local code = C.ERR_peek_last_error() + last_err_code = code == 0 and last_err_code or code + + return last_err_code +end + +local function get_lib_error_string(code) + code = code or get_last_error_code() + + local msg = C.ERR_lib_error_string(code) + if msg == nil then + return "unknown library" + end + + return ffi_str(msg) +end + +local function get_reason_error_string(code) + code = code or get_last_error_code() + + local msg = C.ERR_reason_error_string(code) + if msg == nil then + return "" + end + + return ffi_str(msg) +end local function format_error(ctx, code, all_errors) local errors = {} if code then table.insert(errors, string.format("code: %d", code or 0)) end + + local line = ctypes.ptr_of_int() + local path = constchar_ptrptr() + local func = constchar_ptrptr() + -- get the OpenSSL errors while C.ERR_peek_error() ~= 0 do - local line = ctypes.ptr_of_int() - local path = constchar_ptrptr() local code if all_errors then - code = C.ERR_get_error_line(path, line) + if OPENSSL_3X then + code = C.ERR_get_error_all(path, line, func, nil, nil) + else + code = C.ERR_get_error_line(path, line) + end else - code = C.ERR_peek_last_error_line(path, line) + if OPENSSL_3X then + code = C.ERR_peek_last_error_all(path, line, func, nil, nil) + else + code = C.ERR_peek_last_error_line(path, line) + end end + last_err_code = code + local abs_path = ffi_str(path[0]) -- ../crypto/asn1/a_d2i_fp.c => crypto/asn1/a_d2i_fp.c local start = abs_path:find("/") @@ -33,10 +76,23 @@ local function format_error(ctx, code, all_errors) abs_path = abs_path:sub(start+1) end - C.ERR_error_string_n(code, buf, ffi_sizeof(buf)) - table.insert(errors, string.format("%s:%d:%s", - abs_path, line[0], ffi_str(buf)) - ) + local err_line + + if OPENSSL_3X then + local reason_msg = get_reason_error_string(code) + local lib_msg = get_lib_error_string(code) + -- error:04800065:PEM routines:PEM_do_header:bad decrypt:crypto/pem/pem_lib.c:467: + err_line = string.format("error:%X:%s:%s:%s:%s:%d:", + code, lib_msg, ffi_str(func[0]), reason_msg, abs_path, line[0]) + else + local buf = ffi.new('char[256]') + + C.ERR_error_string_n(code, buf, ffi_sizeof(buf)) + err_line = string.format("%s:%d:%s", + abs_path, line[0], ffi_str(buf)) + end + + table.insert(errors, err_line) if not all_errors then break @@ -59,4 +115,7 @@ end return { format_error = format_error, format_all_error = format_all_error, -} \ No newline at end of file + get_last_error_code = get_last_error_code, + get_lib_error_string = get_lib_error_string, + get_reason_error_string = get_reason_error_string, +} diff --git a/lib/resty/openssl/include/bn.lua b/lib/resty/openssl/include/bn.lua index ac6dee76c..7c83aad64 100644 --- a/lib/resty/openssl/include/bn.lua +++ b/lib/resty/openssl/include/bn.lua @@ -1,7 +1,6 @@ local ffi = require "ffi" require "resty.openssl.include.ossl_typ" -local OPENSSL_3X = require("resty.openssl.version").OPENSSL_3X local BN_ULONG if ffi.abi('64bit') then @@ -33,6 +32,9 @@ ffi.cdef( char *BN_bn2hex(const BIGNUM *a); char *BN_bn2dec(const BIGNUM *a); + int BN_bn2mpi(const BIGNUM *a, unsigned char *to); + BIGNUM *BN_mpi2bn(const unsigned char *s, int len, BIGNUM *ret); + void BN_set_negative(BIGNUM *a, int n); int BN_is_negative(const BIGNUM *a); @@ -60,7 +62,6 @@ ffi.cdef( int BN_cmp(BIGNUM *a, BIGNUM *b); int BN_ucmp(BIGNUM *a, BIGNUM *b); - // openssl >= 1.1 only int BN_is_zero(BIGNUM *a); int BN_is_one(BIGNUM *a); int BN_is_word(BIGNUM *a, ]] .. BN_ULONG ..[[ w); @@ -70,10 +71,4 @@ ffi.cdef( int BN_generate_prime_ex(BIGNUM *ret,int bits,int safe, const BIGNUM *add, const BIGNUM *rem, BN_GENCB *cb); ]] -) - -if OPENSSL_3X then - ffi.cdef [[ - int BN_check_prime(const BIGNUM *p, BN_CTX *ctx, BN_GENCB *cb); - ]] -end \ No newline at end of file +) \ No newline at end of file diff --git a/lib/resty/openssl/include/err.lua b/lib/resty/openssl/include/err.lua index 142098c5f..592329607 100644 --- a/lib/resty/openssl/include/err.lua +++ b/lib/resty/openssl/include/err.lua @@ -1,9 +1,30 @@ local ffi = require "ffi" +require "resty.openssl.include.ossl_typ" +local OPENSSL_3X = require("resty.openssl.version").OPENSSL_3X + ffi.cdef [[ unsigned long ERR_peek_error(void); - unsigned long ERR_peek_last_error_line(const char **file, int *line); - unsigned long ERR_get_error_line(const char **file, int *line); + unsigned long ERR_peek_last_error(void); void ERR_clear_error(void); void ERR_error_string_n(unsigned long e, char *buf, size_t len); + const char *ERR_lib_error_string(unsigned long e); + const char *ERR_reason_error_string(unsigned long e); ]] + +if OPENSSL_3X then + ffi.cdef [[ + unsigned long ERR_get_error_all(const char **file, int *line, + const char **func, + const char **data, int *flags); + unsigned long ERR_peek_last_error_all(const char **file, int *line, + const char **func, + const char **data, int *flags); + ]] + +else + ffi.cdef [[ + unsigned long ERR_get_error_line(const char **file, int *line); + unsigned long ERR_peek_last_error_line(const char **file, int *line); + ]] +end \ No newline at end of file diff --git a/lib/resty/openssl/include/evp.lua b/lib/resty/openssl/include/evp.lua index 48c6ad771..3ae1db277 100644 --- a/lib/resty/openssl/include/evp.lua +++ b/lib/resty/openssl/include/evp.lua @@ -44,15 +44,24 @@ local _M = { EVP_PKEY_X448 = C.OBJ_txt2nid("X448"), EVP_PKEY_ED448 = C.OBJ_txt2nid("ED448"), - EVP_PKEY_OP_PARAMGEN = bit.lshift(1, 1), - EVP_PKEY_OP_KEYGEN = bit.lshift(1, 2), - EVP_PKEY_OP_SIGN = bit.lshift(1, 3), - EVP_PKEY_OP_VERIFY = bit.lshift(1, 4), - EVP_PKEY_OP_DERIVE = OPENSSL_3X and bit.lshift(1, 12) or bit.lshift(1, 10), + EVP_CTRL_AEAD_SET_IVLEN = 0x9, + EVP_CTRL_AEAD_GET_TAG = 0x10, + EVP_CTRL_AEAD_SET_TAG = 0x11, + + -- remove EVP_PKEY_OP_* and EVP_PKEY_CTRL_* after openssl 1.1.1 support is dropped + EVP_PKEY_OP_PARAMGEN = not OPENSSL_3X and bit.lshift(1, 1) or nil, + EVP_PKEY_OP_KEYGEN = not OPENSSL_3X and bit.lshift(1, 2) or nil, + EVP_PKEY_OP_SIGN = not OPENSSL_3X and bit.lshift(1, 3) or nil, + EVP_PKEY_OP_VERIFY = not OPENSSL_3X and bit.lshift(1, 4) or nil, + EVP_PKEY_OP_VERIFYRECOVER = not OPENSSL_3X and bit.lshift(1, 5) or nil, + EVP_PKEY_OP_SIGNCTX = not OPENSSL_3X and bit.lshift(1, 6) or nil, + EVP_PKEY_OP_VERIFYCTX = not OPENSSL_3X and bit.lshift(1, 7) or nil, + EVP_PKEY_OP_ENCRYPT = not OPENSSL_3X and bit.lshift(1, 8) or nil, + EVP_PKEY_OP_DECRYPT = not OPENSSL_3X and bit.lshift(1, 9) or nil, + EVP_PKEY_OP_DERIVE = not OPENSSL_3X and bit.lshift(1, 10) or nil, EVP_PKEY_ALG_CTRL = EVP_PKEY_ALG_CTRL, - EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN = EVP_PKEY_ALG_CTRL + 1, EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID = EVP_PKEY_ALG_CTRL + 1, EVP_PKEY_CTRL_EC_PARAM_ENC = EVP_PKEY_ALG_CTRL + 2, @@ -60,10 +69,8 @@ local _M = { EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP = EVP_PKEY_ALG_CTRL + 4, EVP_PKEY_CTRL_RSA_PADDING = EVP_PKEY_ALG_CTRL + 1, EVP_PKEY_CTRL_RSA_PSS_SALTLEN = EVP_PKEY_ALG_CTRL + 2, - - EVP_CTRL_AEAD_SET_IVLEN = 0x9, - EVP_CTRL_AEAD_GET_TAG = 0x10, - EVP_CTRL_AEAD_SET_TAG = 0x11, + EVP_PKEY_CTRL_RSA_MGF1_MD = EVP_PKEY_ALG_CTRL + 5, + EVP_PKEY_CTRL_RSA_OAEP_MD = EVP_PKEY_ALG_CTRL + 9, EVP_PKEY_CTRL_TLS_MD = EVP_PKEY_ALG_CTRL, EVP_PKEY_CTRL_TLS_SECRET = EVP_PKEY_ALG_CTRL + 1, @@ -81,6 +88,12 @@ local _M = { EVP_PKEY_CTRL_SCRYPT_MAXMEM_BYTES = EVP_PKEY_ALG_CTRL + 13, } +if not OPENSSL_3X then + _M.EVP_PKEY_OP_CRYPT = _M.EVP_PKEY_OP_ENCRYPT + _M.EVP_PKEY_OP_DECRYPT + _M.EVP_PKEY_OP_SIG = _M.EVP_PKEY_OP_SIGN + _M.EVP_PKEY_OP_VERIFY + _M.EVP_PKEY_OP_VERIFYRECOVER + + _M.EVP_PKEY_OP_SIGNCTX + _M.EVP_PKEY_OP_VERIFYCTX +end + -- clean up error occurs during OBJ_txt2* C.ERR_clear_error() diff --git a/lib/resty/openssl/include/evp/pkey.lua b/lib/resty/openssl/include/evp/pkey.lua index 40184b06b..8bdd809ee 100644 --- a/lib/resty/openssl/include/evp/pkey.lua +++ b/lib/resty/openssl/include/evp/pkey.lua @@ -81,6 +81,9 @@ ffi.cdef [[ int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey); int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx); int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey); + + int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, + const char *value); ]] local _M = {} @@ -102,6 +105,10 @@ if OPENSSL_3X then int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int pad); int EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int len); + int EVP_PKEY_CTX_set_rsa_mgf1_md_name(EVP_PKEY_CTX *ctx, const char *mdname, + const char *mdprops); + int EVP_PKEY_CTX_set_rsa_oaep_md_name(EVP_PKEY_CTX *ctx, const char *mdname, + const char *mdprops); int EVP_PKEY_CTX_set_dh_paramgen_prime_len(EVP_PKEY_CTX *ctx, int pbits); @@ -121,6 +128,10 @@ if OPENSSL_3X then return C.EVP_PKEY_CTX_set_ec_param_enc(pctx, param_enc) end + _M.EVP_PKEY_CTX_set_dh_paramgen_prime_len = function(pctx, pbits) + return C.EVP_PKEY_CTX_set_dh_paramgen_prime_len(pctx, pbits) + end + _M.EVP_PKEY_CTX_set_rsa_keygen_bits = function(pctx, mbits) return C.EVP_PKEY_CTX_set_rsa_keygen_bits(pctx, mbits) end @@ -134,8 +145,11 @@ if OPENSSL_3X then _M.EVP_PKEY_CTX_set_rsa_pss_saltlen = function(pctx, len) return C.EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, len) end - _M.EVP_PKEY_CTX_set_dh_paramgen_prime_len = function(pctx, pbits) - return C.EVP_PKEY_CTX_set_dh_paramgen_prime_len(pctx, pbits) + _M.EVP_PKEY_CTX_set_rsa_mgf1_md_name = function(pctx, name ,props) + return C.EVP_PKEY_CTX_set_rsa_mgf1_md_name(pctx, name, props) + end + _M.EVP_PKEY_CTX_set_rsa_oaep_md_name = function(pctx, name, props) + return C.EVP_PKEY_CTX_set_rsa_oaep_md_name(pctx, name, props) end else @@ -154,6 +168,13 @@ else param_enc, nil) end + _M.EVP_PKEY_CTX_set_dh_paramgen_prime_len = function(pctx, pbits) + return C.EVP_PKEY_CTX_ctrl(pctx, + evp.EVP_PKEY_DH, evp.EVP_PKEY_OP_PARAMGEN, + evp.EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN, + pbits, nil) + end + _M.EVP_PKEY_CTX_set_rsa_keygen_bits = function(pctx, mbits) return C.EVP_PKEY_CTX_ctrl(pctx, evp.EVP_PKEY_RSA, @@ -183,11 +204,27 @@ else len, nil) end - _M.EVP_PKEY_CTX_set_dh_paramgen_prime_len = function(pctx, pbits) + _M.EVP_PKEY_CTX_set_rsa_mgf1_md_name = function(pctx, name, _) + local md = C.EVP_get_digestbyname(name) + if not md then + return -1, "unknown digest: " .. name + end return C.EVP_PKEY_CTX_ctrl(pctx, - evp.EVP_PKEY_DH, evp.EVP_PKEY_OP_PARAMGEN, - evp.EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN, - pbits, nil) + evp.EVP_PKEY_RSA, + evp.EVP_PKEY_OP_SIG + evp.EVP_PKEY_OP_TYPE_CRYPT, + evp.EVP_PKEY_CTRL_RSA_MGF1_MD, + 0, ffi.cast("void *", md)) + end + _M.EVP_PKEY_CTX_set_rsa_oaep_md_name = function(pctx, name, _) + local md = C.EVP_get_digestbyname(name) + if not md then + return -1, "unknown digest: " .. name + end + return C.EVP_PKEY_CTX_ctrl(pctx, + evp.EVP_PKEY_RSA, + evp.EVP_PKEY_OP_CRYPT, + evp.EVP_PKEY_CTRL_RSA_OAEP_MD, + 0, ffi.cast("void *", md)) end end diff --git a/lib/resty/openssl/kdf.lua b/lib/resty/openssl/kdf.lua index d7555151c..c6b3ac4d1 100644 --- a/lib/resty/openssl/kdf.lua +++ b/lib/resty/openssl/kdf.lua @@ -13,6 +13,8 @@ local format_error = require("resty.openssl.err").format_error local version_text = require("resty.openssl.version").version_text local OPENSSL_3X = require("resty.openssl.version").OPENSSL_3X local ctypes = require "resty.openssl.auxiliary.ctypes" +local nkeys = require "resty.openssl.auxiliary.compat".nkeys +local log_warn = require "resty.openssl.auxiliary.compat".log_warn --[[ https://wiki.openssl.org/index.php/EVP_Key_Derivation @@ -251,7 +253,7 @@ function _M.derive(options) local md_size = OPENSSL_3X and C.EVP_MD_get_size(md) or C.EVP_MD_size(md) if options.outlen ~= md_size then options.outlen = md_size - ngx.log(ngx.WARN, "hkdf_mode EXTRACT_ONLY outputs fixed length of ", md_size, + log_warn("hkdf_mode EXTRACT_ONLY outputs fixed length of ", md_size, " key, ignoring options.outlen") end outlen[0] = md_size @@ -311,6 +313,7 @@ function _M.new(typ, properties) algo = algo, buf = buf, buf_size = buf_size, + schema = nil, }, mt), nil end @@ -344,14 +347,16 @@ function _M:derive(outlen, options, options_count) if options_count then options_count = options_count - 1 else - options_count = 0 - for k, v in pairs(options) do options_count = options_count + 1 end + options_count = nkeys(options) end local param, err if options_count > 0 then - local schema = self:settable_params(true) -- raw schema - param, err = param_lib.construct(options, nil, schema) + if not self.schema then + self.schema = self:settable_params(true) -- raw schema + end + + param, err = param_lib.construct(options, nil, self.schema) if err then return nil, "kdf:derive: " .. err end diff --git a/lib/resty/openssl/mac.lua b/lib/resty/openssl/mac.lua index accfbc476..7712399f3 100644 --- a/lib/resty/openssl/mac.lua +++ b/lib/resty/openssl/mac.lua @@ -41,7 +41,8 @@ function _M.new(key, typ, cipher, digest, properties) params.cipher = cipher local p = param_lib.construct(params, 2, param_types) - local code = C.EVP_MAC_init(ctx, key, #key, p) + local keyl = #key + local code = C.EVP_MAC_init(ctx, key, keyl, p) if code ~= 1 then return nil, format_error(string.format("mac.new: invalid cipher or digest type")) end @@ -53,6 +54,7 @@ function _M.new(key, typ, cipher, digest, properties) algo = algo, buf = ctypes.uchar_array(md_size), buf_size = md_size, + _reset = function() return C.EVP_MAC_init(ctx, key, keyl, p) end, }, mt), nil end @@ -73,7 +75,7 @@ _M.settable_params, _M.set_params, _M.gettable_params, _M.get_param = param_lib. function _M:update(...) for _, s in ipairs({...}) do if C.EVP_MAC_update(self.ctx, s, #s) ~= 1 then - return false, format_error("digest:update") + return false, format_error("mac:update") end end return true, nil @@ -81,17 +83,25 @@ end function _M:final(s) if s then - local _, err = self:update(s) - if err then - return nil, err + if C.EVP_MAC_update(self.ctx, s, #s) ~= 1 then + return false, format_error("mac:final") end end local length = ctypes.ptr_of_size_t() if C.EVP_MAC_final(self.ctx, self.buf, length, self.buf_size) ~= 1 then - return nil, format_error("digest:final: EVP_MAC_final") + return nil, format_error("mac:final: EVP_MAC_final") end return ffi_str(self.buf, length[0]) end +function _M:reset() + local code = self._reset() + if code ~= 1 then + return false, format_error("mac:reset") + end + + return true +end + return _M diff --git a/lib/resty/openssl/param.lua b/lib/resty/openssl/param.lua index 2c8dcea65..add0fa0eb 100644 --- a/lib/resty/openssl/param.lua +++ b/lib/resty/openssl/param.lua @@ -8,6 +8,7 @@ require "resty.openssl.include.param" local format_error = require("resty.openssl.err").format_error local bn_lib = require("resty.openssl.bn") local null = require("resty.openssl.auxiliary.ctypes").null +local nkeys = require "resty.openssl.auxiliary.compat".nkeys local OSSL_PARAM_INTEGER = 1 local OSSL_PARAM_UNSIGNED_INTEGER = 2 @@ -22,8 +23,7 @@ local buf_param_key = {} local function construct(buf_t, length, types_map, types_size) if not length then - length = 0 - for k, v in pairs(buf_t) do length = length + 1 end + length = nkeys(buf_t) end local params = ffi_new("OSSL_PARAM[?]", length + 1) diff --git a/lib/resty/openssl/pkey.lua b/lib/resty/openssl/pkey.lua index 8dba4dd52..5ad4a118f 100644 --- a/lib/resty/openssl/pkey.lua +++ b/lib/resty/openssl/pkey.lua @@ -26,6 +26,8 @@ local ctx_lib = require "resty.openssl.ctx" local ctypes = require "resty.openssl.auxiliary.ctypes" local ecdsa_util = require "resty.openssl.auxiliary.ecdsa" local format_error = require("resty.openssl.err").format_error +local log_warn = require "resty.openssl.auxiliary.compat".log_warn +local log_debug = require "resty.openssl.auxiliary.compat".log_debug local OPENSSL_3X = require("resty.openssl.version").OPENSSL_3X @@ -67,7 +69,7 @@ local function load_pem_der(txt, opts, funcs) return nil, "explictly load private or public key from JWK format is not supported" end - ngx.log(ngx.DEBUG, "load key using fmt: ", fmt, ", type: ", typ) + log_debug("load key using fmt: ", fmt, ", type: ", typ) local bio = C.BIO_new_mem_buf(txt, #txt) if bio == nil then @@ -89,7 +91,7 @@ local function load_pem_der(txt, opts, funcs) if fmt == "JWK" then return nil, err end - ngx.log(ngx.DEBUG, "jwk decode failed: ", err, ", continuing") + log_debug("jwk decode failed: ", err, ", continuing") end else -- #define BIO_CTRL_RESET 1 @@ -113,7 +115,7 @@ local function load_pem_der(txt, opts, funcs) local p = opts.passphrase_cb() local len = #p -- 1 byte for \0 if len > size then - ngx.log(ngx.WARN, "pkey:load_pem_der: passphrase truncated from ", len, " to ", size) + log_warn("pkey:load_pem_der: passphrase truncated from ", len, " to ", size) len = size end ffi_copy(buf, p, len) @@ -127,7 +129,7 @@ local function load_pem_der(txt, opts, funcs) end if ctx ~= nil then - ngx.log(ngx.DEBUG, "pkey:load_pem_der: loaded pkey using function ", f) + log_debug("pkey:load_pem_der: loaded pkey using function ", f) -- pkcs1 functions create a rsa rather than evp_pkey -- disable the checking in openssl 3.0 for sail safe @@ -160,6 +162,40 @@ local function load_pem_der(txt, opts, funcs) return ctx, nil end +local function _pctx_ctrl_str(pctx, opts) + if not opts then + return true + end + + if opts.mgf1_md and pkey_macro.EVP_PKEY_CTX_set_rsa_mgf1_md_name(pctx, opts.mgf1_md, nil) ~= 1 then + return nil, format_error("EVP_PKEY_CTX_set_rsa_mgf1_md_name") + end + + if opts.oaep_md and pkey_macro.EVP_PKEY_CTX_set_rsa_oaep_md_name(pctx, opts.oaep_md, nil) ~= 1 then + return nil, format_error("EVP_PKEY_CTX_set_rsa_oaep_md_name") + end + + if opts.pss_saltlen and pkey_macro.EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, opts.pss_saltlen) ~= 1 then + return nil, format_error("EVP_PKEY_CTX_set_rsa_pss_saltlen") + end + + + for _, c in ipairs(opts) do + if type(c) == "string" then + local k, v = string.match(c, "([_%w]+):([_%w]+)") + if not k or not v then + return nil, "unknown ctrl str: ".. c + end + + if C.EVP_PKEY_CTX_ctrl_str(pctx, k, v) ~= 1 then + return nil, format_error(string.format('EVP_PKEY_CTX_ctrl_str(%s, "%s", "%s")', pctx, k, v)) + end + end + end + return true +end + + local function generate_param(key_type, config) if key_type == evp_macro.EVP_PKEY_DH then local dh_group = config.group @@ -222,6 +258,11 @@ local function generate_param(key_type, config) end end + local ok, err = _pctx_ctrl_str(pctx, config) + if not ok then + return nil, "pkey:generate_param: " .. err + end + local ctx_ptr = ffi_new("EVP_PKEY*[1]") if C.EVP_PKEY_paramgen(pctx, ctx_ptr) ~= 1 then return nil, format_error("EVP_PKEY_paramgen") @@ -347,6 +388,12 @@ local function generate_key(config) end end end + + local ok, err = _pctx_ctrl_str(pctx, config) + if not ok then + return nil, "pkey:generate_key: " .. err + end + local ctx_ptr = ffi_new("EVP_PKEY*[1]") -- TODO: move to use EVP_PKEY_gen after drop support for <1.1.1 if C.EVP_PKEY_keygen(pctx, ctx_ptr) ~= 1 then @@ -500,7 +547,6 @@ function _M.new(s, opts) local self = setmetatable({ ctx = ctx, pkey_ctx = nil, - rsa_padding = nil, key_type = key_type, key_type_is_ecx = key_type_is_ecx, buf = ctypes.uchar_array(buf_size), @@ -613,7 +659,11 @@ local ASYMMETRIC_OP_DECRYPT = 0x2 local ASYMMETRIC_OP_SIGN_RAW = 0x4 local ASYMMETRIC_OP_VERIFY_RECOVER = 0x8 -local function asymmetric_routine(self, s, op, padding) +local function asymmetric_routine(self, s, op, padding, opts) + if type(s) ~= "string" then + return nil, "pkey:asymmetric_routine: expect a string at #1" + end + local pkey_ctx if self.key_type == evp_macro.EVP_PKEY_RSA then @@ -627,9 +677,8 @@ local function asymmetric_routine(self, s, op, padding) end end - if self.pkey_ctx ~= nil and - (self.key_type ~= evp_macro.EVP_PKEY_RSA or self.rsa_padding == padding) then - pkey_ctx = self.pkey_ctx + if self.pkey_ctx ~= nil and self.key_type ~= evp_macro.EVP_PKEY_RSA then + pkey_ctx = self.pkey_ctx else pkey_ctx = C.EVP_PKEY_CTX_new(self.ctx, nil) if pkey_ctx == nil then @@ -666,11 +715,14 @@ local function asymmetric_routine(self, s, op, padding) end -- EVP_PKEY_CTX_ctrl must be called after *_init - if self.key_type == evp_macro.EVP_PKEY_RSA and padding then - if pkey_macro.EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, padding) ~= 1 then - return nil, format_error("pkey:asymmetric_routine EVP_PKEY_CTX_set_rsa_padding") - end - self.rsa_padding = padding + if self.key_type == evp_macro.EVP_PKEY_RSA and padding and + pkey_macro.EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, padding) ~= 1 then + return nil, format_error("pkey:asymmetric_routine EVP_PKEY_CTX_set_rsa_padding") + end + + local ok, err = _pctx_ctrl_str(pkey_ctx, opts) + if not ok then + return nil, "pkey:asymmetric_routine: " .. err end local length = ptr_of_size_t(self.buf_size) @@ -684,40 +736,30 @@ end _M.PADDINGS = rsa_macro.paddings -function _M:encrypt(s, padding) - return asymmetric_routine(self, s, ASYMMETRIC_OP_ENCRYPT, padding) +function _M:encrypt(s, padding, opts) + return asymmetric_routine(self, s, ASYMMETRIC_OP_ENCRYPT, padding, opts) end -function _M:decrypt(s, padding) - return asymmetric_routine(self, s, ASYMMETRIC_OP_DECRYPT, padding) +function _M:decrypt(s, padding, opts) + return asymmetric_routine(self, s, ASYMMETRIC_OP_DECRYPT, padding, opts) end -function _M:sign_raw(s, padding) +function _M:sign_raw(s, padding, opts) -- TODO: temporary hack before OpenSSL has proper check for existence of private key if self.key_type_is_ecx and not self:is_private() then return nil, "pkey:sign_raw: missing private key" end - return asymmetric_routine(self, s, ASYMMETRIC_OP_SIGN_RAW, padding) + return asymmetric_routine(self, s, ASYMMETRIC_OP_SIGN_RAW, padding, opts) end -function _M:verify_recover(s, padding) - return asymmetric_routine(self, s, ASYMMETRIC_OP_VERIFY_RECOVER, padding) +function _M:verify_recover(s, padding, opts) + return asymmetric_routine(self, s, ASYMMETRIC_OP_VERIFY_RECOVER, padding, opts) end local evp_pkey_ctx_ptr_ptr_ct = ffi.typeof('EVP_PKEY_CTX*[1]') local function sign_verify_prepare(self, fint, md_alg, padding, opts) - local pkey_ctx - - if self.key_type == evp_macro.EVP_PKEY_RSA and padding then - pkey_ctx = C.EVP_PKEY_CTX_new(self.ctx, nil) - if pkey_ctx == nil then - return nil, format_error("pkey:sign_verify_prepare EVP_PKEY_CTX_new()") - end - ffi_gc(pkey_ctx, C.EVP_PKEY_CTX_free) - end - local md_ctx = C.EVP_MD_CTX_new() if md_ctx == nil then return nil, "pkey:sign_verify_prepare: EVP_MD_CTX_new() failed" @@ -737,22 +779,19 @@ local function sign_verify_prepare(self, fint, md_alg, padding, opts) end local ppkey_ctx = evp_pkey_ctx_ptr_ptr_ct() - ppkey_ctx[0] = pkey_ctx if fint(md_ctx, ppkey_ctx, algo, nil, self.ctx) ~= 1 then return nil, format_error("pkey:sign_verify_prepare: Init failed") end - if self.key_type == evp_macro.EVP_PKEY_RSA then - if padding then - if pkey_macro.EVP_PKEY_CTX_set_rsa_padding(ppkey_ctx[0], padding) ~= 1 then - return nil, format_error("pkey:sign_verify_prepare EVP_PKEY_CTX_set_rsa_padding") - end - end - if opts and opts.pss_saltlen and padding ~= rsa_macro.paddings.RSA_PKCS1_PSS_PADDING then - if pkey_macro.EVP_PKEY_CTX_set_rsa_pss_saltlen(ppkey_ctx[0], opts.pss_saltlen) ~= 1 then - return nil, format_error("pkey:sign_verify_prepare EVP_PKEY_CTX_set_rsa_pss_saltlen") - end - end + -- EVP_PKEY_CTX_ctrl must be called after *_init + if self.key_type == evp_macro.EVP_PKEY_RSA and padding and + pkey_macro.EVP_PKEY_CTX_set_rsa_padding(ppkey_ctx[0], padding) ~= 1 then + return nil, format_error("pkey:sign_verify_prepare EVP_PKEY_CTX_set_rsa_padding") + end + + local ok, err = _pctx_ctrl_str(ppkey_ctx[0], opts) + if not ok then + return nil, "pkey:sign_verify_prepare: " .. err end return md_ctx diff --git a/lib/resty/openssl/version.lua b/lib/resty/openssl/version.lua index b13777d68..fa7d8d0d0 100644 --- a/lib/resty/openssl/version.lua +++ b/lib/resty/openssl/version.lua @@ -2,11 +2,30 @@ local ffi = require "ffi" local C = ffi.C local ffi_str = ffi.string +local log_debug = require "resty.openssl.auxiliary.compat".log_debug + +local libcrypto_name +local lib_patterns = { + "%s", "%s.so.3", "%s.so.1.1", "%s.so.1.0" +} + +local function load_library() + for _, pattern in ipairs(lib_patterns) do + -- true: load to global namespae + local pok, _ = pcall(ffi.load, string.format(pattern, "crypto"), true) + if pok then + libcrypto_name = string.format(pattern, "crypto") + ffi.load(string.format(pattern, "ssl"), true) + + log_debug("loaded crypto library: ", libcrypto_name) + return libcrypto_name + end + end + + return false, "unable to load crypto library" +end ffi.cdef[[ - // 1.0 - unsigned long SSLeay(void); - const char *SSLeay_version(int t); // >= 1.1 unsigned long OpenSSL_version_num(); const char *OpenSSL_version(int t); @@ -15,49 +34,38 @@ ffi.cdef[[ ]] local version_func, info_func -local types_table +local types_table = { + VERSION = 0, + CFLAGS = 1, + BUILT_ON = 2, + PLATFORM = 3, + DIR = 4, + ENGINES_DIR = 5, + VERSION_STRING = 6, + FULL_VERSION_STRING = 7, + MODULES_DIR = 8, + CPU_INFO = 9, +} --- >= 1.1 -local ok, version_num = pcall(function() +local get_version = function() local num = C.OpenSSL_version_num() version_func = C.OpenSSL_version - types_table = { - VERSION = 0, - CFLAGS = 1, - BUILT_ON = 2, - PLATFORM = 3, - DIR = 4, - ENGINES_DIR = 5, - VERSION_STRING = 6, - FULL_VERSION_STRING = 7, - MODULES_DIR = 8, - CPU_INFO = 9, - } return num -end) - - -if not ok then - -- 1.0.x - ok, version_num = pcall(function() - local num = C.SSLeay() - version_func = C.SSLeay_version - types_table = { - VERSION = 0, - CFLAGS = 2, - BUILT_ON = 3, - PLATFORM = 4, - DIR = 5, - } - return num - end) end +local ok, version_num = pcall(get_version) +if not ok then + ok, version_num = pcall(load_library) + if ok then + -- try again + ok, version_num = pcall(get_version) + end +end if not ok then error(string.format("OpenSSL has encountered an error: %s; is OpenSSL library loaded?", tostring(version_num))) -elseif type(version_num) == 'number' and version_num < 0x10000000 then +elseif type(version_num) == 'number' and version_num < 0x10101000 then error(string.format("OpenSSL version %s is not supported", tostring(version_num or 0))) elseif not version_num then error("Can not get OpenSSL version") diff --git a/lua-resty-openssl-1.0.2-1.rockspec b/lua-resty-openssl-1.2.0-1.rockspec similarity index 98% rename from lua-resty-openssl-1.0.2-1.rockspec rename to lua-resty-openssl-1.2.0-1.rockspec index 0413f006d..ade507dd7 100644 --- a/lua-resty-openssl-1.0.2-1.rockspec +++ b/lua-resty-openssl-1.2.0-1.rockspec @@ -1,8 +1,8 @@ package = "lua-resty-openssl" -version = "1.0.2-1" +version = "1.2.0-1" source = { url = "git+https://github.com/fffonion/lua-resty-openssl.git", - tag = "1.0.2" + tag = "1.2.0" } description = { detailed = "FFI-based OpenSSL binding for LuaJIT.", @@ -15,6 +15,7 @@ build = { ["resty.openssl"] = "lib/resty/openssl.lua", ["resty.openssl.asn1"] = "lib/resty/openssl/asn1.lua", ["resty.openssl.auxiliary.bio"] = "lib/resty/openssl/auxiliary/bio.lua", + ["resty.openssl.auxiliary.compat"] = "lib/resty/openssl/auxiliary/compat.lua", ["resty.openssl.auxiliary.ctypes"] = "lib/resty/openssl/auxiliary/ctypes.lua", ["resty.openssl.auxiliary.ecdsa"] = "lib/resty/openssl/auxiliary/ecdsa.lua", ["resty.openssl.auxiliary.jwk"] = "lib/resty/openssl/auxiliary/jwk.lua", diff --git a/scripts/templates/x509_tests.j2 b/scripts/templates/x509_tests.j2 index a108791b6..4517b58c4 100644 --- a/scripts/templates/x509_tests.j2 +++ b/scripts/templates/x509_tests.j2 @@ -1,7 +1,9 @@ -{%- set ns = namespace(idx=test_idx) %} -{%- for f in module.fields %} - {%- if f.type in tests.types and not f.skip_tests%} + + +{%+ set ns = namespace(idx=test_idx) -%} +{%- for f in module.fields -%} + {%- if f.type in tests.types and not f.skip_tests -%} === TEST {{ ns.idx }}: {{ modname }}:get_{{ f.field }} (AUTOGEN) --- http_config eval: $::HttpConfig --- config @@ -24,9 +26,10 @@ "{{ f.sample_printable }}" --- no_error_log [error] - {%- set ns.idx = ns.idx + 1 %} -=== TEST {{ ns.idx }}: {{ modname }}:set_{{ f.field }} (AUTOGEN) + + +=== TEST {{ ns.idx + 1 }}: {{ modname }}:set_{{ f.field }} (AUTOGEN) --- http_config eval: $::HttpConfig --- config location =/t { @@ -61,11 +64,14 @@ "ok" --- no_error_log [error] - {%- set ns.idx = ns.idx + 1 %} - {%- endif %} - {%- if f.extension_nid and not f.skip_tests %} -=== TEST {{ ns.idx + 1 }}: {{ modname }}:get/set_{{ f.field }}_critical (AUTOGEN) + + +{%+ set nop=1 -%} + {%- set ns.idx = ns.idx + 2 -%} + {%- endif -%} + {%- if f.extension_nid and not f.skip_tests -%} +=== TEST {{ ns.idx }}: {{ modname }}:get/set_{{ f.field }}_critical (AUTOGEN) --- http_config eval: $::HttpConfig --- config location =/t { @@ -86,11 +92,14 @@ true --- no_error_log [error] - {%- set ns.idx = ns.idx + 1 %} - {%- endif %} -{%- endfor %} -=== TEST {{ ns.idx + 1 }}: {{ modname }}:get_get_signature_name (AUTOGEN) + + +{%+ set nop=1 -%} + {%- set ns.idx = ns.idx + 1 -%} + {%- endif -%} +{%- endfor -%} +=== TEST {{ ns.idx }}: {{ modname }}:get_signature_name (AUTOGEN) --- http_config eval: $::HttpConfig --- config location =/t { diff --git a/scripts/types_test.py b/scripts/types_test.py index 5d08fa6a1..642c527b5 100644 --- a/scripts/types_test.py +++ b/scripts/types_test.py @@ -3,7 +3,7 @@ tests = { { "bn": { "new_from": "new(math.random(1, 2333333))", - "print": "to_hex():upper", + "print": "to_hex", }, "number": { "new_from": "ngx.time()", diff --git a/t/fips.t b/t/fips.t index 673251c56..53eb55fc7 100644 --- a/t/fips.t +++ b/t/fips.t @@ -25,6 +25,7 @@ our $HttpConfig = qq{ run_tests(); __DATA__ + === TEST 1: FIPS mode can be turned on and off --- http_config eval: $::HttpConfig --- config @@ -51,6 +52,8 @@ false --- no_error_log [error] + + === TEST 2: CIPHER, MD and PKEY provider is directed to fips --- http_config eval: $::HttpConfig --- config @@ -77,6 +80,8 @@ fips --- no_error_log [error] + + === TEST 3: Non-FIPS compliant algorithms are not allowed --- http_config eval: $::HttpConfig --- config @@ -122,6 +127,8 @@ true --- no_error_log [error] + + === TEST 4: Get FIPS version text --- http_config eval: $::HttpConfig --- config diff --git a/t/openssl.t b/t/openssl.t index 978f61afd..e4e56057c 100644 --- a/t/openssl.t +++ b/t/openssl.t @@ -10,7 +10,7 @@ my $use_luacov = $ENV{'TEST_NGINX_USE_LUACOV'} // ''; my $fips = $ENV{'TEST_NGINX_FIPS'} // ''; our $HttpConfig = qq{ - lua_package_path "$pwd/lib/?.lua;$pwd/lib/?/init.lua;$pwd/../lua-resty-hmac/lib/?.lua;$pwd/../lua-resty-string/lib/?.lua;;"; + lua_package_path "$pwd/lib/?.lua;$pwd/lib/?/init.lua;$pwd/../lua-resty-string/lib/?.lua;;"; init_by_lua_block { if "1" == "$use_luacov" then require 'luacov.tick' @@ -24,6 +24,7 @@ our $HttpConfig = qq{ run_tests(); __DATA__ + === TEST 1: Load ffi openssl library --- http_config eval: $::HttpConfig --- config @@ -42,6 +43,7 @@ __DATA__ [error] + === TEST 2: Luaossl compat pattern --- http_config eval: $::HttpConfig --- config @@ -64,13 +66,14 @@ false [error] + === TEST 3: List cipher algorithms --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { local openssl = require("resty.openssl") - ngx.say(require("cjson").encode(openssl.list_cipher_algorithms())) + ngx.say(require("cjson").encode(openssl.list_cipher_algorithms(true))) local version = require("resty.openssl.version") if not version.OPENSSL_3X then ngx.say("[\"AES-256-GCM @ default\"]") @@ -87,13 +90,15 @@ false --- no_error_log [error] + + === TEST 4: List digest algorithms --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { local openssl = require("resty.openssl") - ngx.say(require("cjson").encode(openssl.list_digest_algorithms())) + ngx.say(require("cjson").encode(openssl.list_digest_algorithms(true))) local version = require("resty.openssl.version") if not version.OPENSSL_3X then ngx.say("[\"SHA2-256 @ default\"]") @@ -110,6 +115,8 @@ false --- no_error_log [error] + + === TEST 5: List mac algorithms --- http_config eval: $::HttpConfig --- config @@ -131,6 +138,8 @@ false --- no_error_log [error] + + === TEST 6: List kdf algorithms --- http_config eval: $::HttpConfig --- config @@ -152,6 +161,8 @@ false --- no_error_log [error] + + === TEST 7: List SSL cipher --- http_config eval: $::HttpConfig --- config diff --git a/t/openssl/asn1.t b/t/openssl/asn1.t index d37b40a94..439d1aefe 100644 --- a/t/openssl/asn1.t +++ b/t/openssl/asn1.t @@ -21,6 +21,7 @@ our $HttpConfig = qq{ run_tests(); __DATA__ + === TEST 1: asn1_to_unix utctime --- http_config eval: $::HttpConfig --- config @@ -43,6 +44,8 @@ __DATA__ --- no_error_log [error] + + === TEST 2: asn1_to_unix utctime, offset --- http_config eval: $::HttpConfig --- config @@ -65,6 +68,8 @@ __DATA__ --- no_error_log [error] + + === TEST 3: asn1_to_unix generalized time --- http_config eval: $::HttpConfig --- config @@ -87,6 +92,8 @@ __DATA__ --- no_error_log [error] + + === TEST 4: asn1_to_unix generalized time, offset --- http_config eval: $::HttpConfig --- config @@ -109,6 +116,8 @@ __DATA__ --- no_error_log [error] + + === TEST 5: asn1_to_unix error on bad format --- http_config eval: $::HttpConfig --- config diff --git a/t/openssl/bn.t b/t/openssl/bn.t index 9a1dc369e..3467db852 100644 --- a/t/openssl/bn.t +++ b/t/openssl/bn.t @@ -9,33 +9,27 @@ my $pwd = cwd(); my $use_luacov = $ENV{'TEST_NGINX_USE_LUACOV'} // ''; our $HttpConfig = qq{ - lua_package_path "$pwd/lib/?.lua;$pwd/lib/?/init.lua;;"; + lua_package_path "$pwd/t/openssl/?.lua;$pwd/lib/?.lua;$pwd/lib/?/init.lua;$pwd/../lua-resty-string/lib/?.lua;;"; init_by_lua_block { if "1" == "$use_luacov" then require 'luacov.tick' jit.off() end + _G.myassert = require("helper").myassert } }; run_tests(); __DATA__ + === TEST 1: New BIGNUM instance correctly --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { - local bn, err = require("resty.openssl.bn").new() - if err then - ngx.log(ngx.ERR, err) - return - end - local b, err = bn:to_binary() - if err then - ngx.log(ngx.ERR, err) - return - end + local bn = myassert(require("resty.openssl.bn").new()) + local b = myassert(bn:to_binary()) ngx.print(ngx.encode_base64(b)) } } @@ -46,21 +40,15 @@ __DATA__ --- error_log bn:to_binary failed + + === TEST 2: New BIGNUM instance from number --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { - local bn, err = require("resty.openssl.bn").new(0x5b25) - if err then - ngx.log(ngx.ERR, err) - return - end - local b, err = bn:to_binary() - if err then - ngx.log(ngx.ERR, err) - return - end + local bn = myassert(require("resty.openssl.bn").new(0x5b25)) + local b = myassert(bn:to_binary()) ngx.print(ngx.encode_base64(b)) } } @@ -71,29 +59,50 @@ bn:to_binary failed --- no_error_log [error] -=== TEST 3: Duplicate the ctx + + +=== TEST 3: New BIGNUM instance from string +--- http_config eval: $::HttpConfig +--- config + location =/t { + content_by_lua_block { + local data = { + ["23333"] = 10, + ["5b25"] = 16, + ["5B25"] = 16, + ["\x5b\x25"] = 2, + ["\x00\x00\x00\x02\x5b\x25"] = 0, + } + for k, v in pairs(data) do + local bn = myassert(require("resty.openssl.bn").new(k, v)) + if bn:to_number() ~= 23333 then + ngx.log(ngx.ERR, bn, " != 23333: ", k, " ", v) + return + end + end + ngx.print("ok") + } + } +--- request + GET /t +--- response_body eval +"ok" +--- no_error_log +[error] + + + +=== TEST 4: Duplicate the ctx --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { require('ffi').cdef('typedef struct bignum_st BIGNUM; void BN_free(BIGNUM *a);') - local bn, err = require("resty.openssl.bn").new(0x5b25) - if err then - ngx.log(ngx.ERR, err) - return - end - local bn2, err = require("resty.openssl.bn").dup(bn.ctx) - if err then - ngx.log(ngx.ERR, err) - return - end + local bn = myassert(require("resty.openssl.bn").new(0x5b25)) + local bn2 = myassert(require("resty.openssl.bn").dup(bn.ctx)) bn = nil collectgarbage("collect") - local b, err = bn2:to_binary() - if err then - ngx.log(ngx.ERR, err) - return - end + local b = myassert(bn2:to_binary()) ngx.print(ngx.encode_base64(b)) } } @@ -104,29 +113,55 @@ bn:to_binary failed --- no_error_log [error] -=== TEST 4: from_binary, to_binary + + +=== TEST 5: set +--- http_config eval: $::HttpConfig +--- config + location =/t { + content_by_lua_block { + local data = { + ["23333"] = 10, + ["5b25"] = 16, + ["5B25"] = 16, + ["\x5b\x25"] = 2, + ["\x00\x00\x00\x02\x5b\x25"] = 0, + } + for k, v in pairs(data) do + local bn = myassert(require("resty.openssl.bn").new(0)) + local new_bn = myassert(bn:set(k, v)) + if bn:to_number() ~= 23333 then + ngx.log(ngx.ERR, bn, " != 23333: ", k, " ", v) + return + end + if tostring(bn.ctx) ~= tostring(new_bn.ctx) then + ngx.log(ngx.ERR, tostring(bn.ctx), " != ", tostring(new_bn.ctx), " (ctx not properly reused)") + return + end + end + ngx.print("ok") + } + } +--- request + GET /t +--- response_body eval +"ok" +--- no_error_log +[error] + + + +=== TEST 6: from_binary, to_binary --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { local d = ngx.decode_base64('WyU=') - local bn, err = require("resty.openssl.bn").from_binary(d) - if err then - ngx.log(ngx.ERR, err) - return - end - local b, err = bn:to_binary() - if err then - ngx.log(ngx.ERR, err) - return - end + local bn = myassert(require("resty.openssl.bn").from_binary(d)) + local b = myassert(bn:to_binary()) ngx.print(ngx.encode_base64(b)) - local b, err = bn:to_binary(10) - if err then - ngx.log(ngx.ERR, err) - return - end + local b = myassert(bn:to_binary(10)) ngx.print(ngx.encode_base64(b)) } } @@ -137,46 +172,34 @@ bn:to_binary failed --- no_error_log [error] -=== TEST 5: from_hex, to_hex + + +=== TEST 7: from_hex, to_hex --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { - local bn, err = require("resty.openssl.bn").from_hex("5B25") - if err then - ngx.log(ngx.ERR, err) - return - end - local b, err = bn:to_hex() - if err then - ngx.log(ngx.ERR, err) - return - end + local bn = myassert(require("resty.openssl.bn").from_hex("5B25")) + local b = myassert(bn:to_hex()) ngx.print(b) } } --- request GET /t ---- response_body_like eval -"5[Bb]25" +--- response_body eval +"5B25" --- no_error_log [error] -=== TEST 6: from_dec, to_dec + + +=== TEST 8: from_dec, to_dec --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { - local bn, err = require("resty.openssl.bn").from_dec("23333") - if err then - ngx.log(ngx.ERR, err) - return - end - local b, err = bn:to_dec() - if err then - ngx.log(ngx.ERR, err) - return - end + local bn = myassert(require("resty.openssl.bn").from_dec("23333")) + local b = myassert(bn:to_dec()) ngx.print(b) } } @@ -187,34 +210,40 @@ bn:to_binary failed --- no_error_log [error] -=== TEST 7: to_number + + +=== TEST 9: from_mpi, to_mpi +--- http_config eval: $::HttpConfig +--- config + location =/t { + content_by_lua_block { + local to_hex = require "resty.string".to_hex + local bn = myassert(require("resty.openssl.bn").from_mpi("\x00\x00\x00\x02\x5b\x25")) + local b = myassert(bn:to_mpi()) + ngx.print(to_hex(b)) + } + } +--- request + GET /t +--- response_body eval +"000000025b25" +--- no_error_log +[error] + + + +=== TEST 10: to_number --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { local bn = require("resty.openssl.bn") - local b, err = bn.new(23333) - if err then - ngx.log(ngx.ERR, err) - return - end - local n, err = b:to_number() - if err then - ngx.log(ngx.ERR, err) - return - end + local b = myassert(bn.new(23333)) + local n = myassert(b:to_number()) ngx.say(tostring(n),type(n)) - b, err = bn.from_dec('184467440737095516161844674407370955161618446744073709551616') - if err then - ngx.log(ngx.ERR, err) - return - end - local n, err = b:to_number() - if err then - ngx.log(ngx.ERR, err) - return - end + b = myassert(bn.from_dec('184467440737095516161844674407370955161618446744073709551616')) + local n = myassert(b:to_number()) ngx.say(tostring(n),type(n)) } @@ -228,27 +257,17 @@ bn:to_binary failed --- no_error_log [error] -=== TEST 8: unary minus + + +=== TEST 11: unary minus --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { - local bn, err = require("resty.openssl.bn").new(23333) - if err then - ngx.log(ngx.ERR, err) - return - end - local b, err = (-bn):to_dec() - if err then - ngx.log(ngx.ERR, err) - return - end + local bn = myassert(require("resty.openssl.bn").new(23333)) + local b = myassert((-bn):to_dec()) ngx.say(b) - local b, err = (-(-bn)):to_dec() - if err then - ngx.log(ngx.ERR, err) - return - end + local b = myassert((-(-bn)):to_dec()) ngx.say(b) } } @@ -261,21 +280,15 @@ bn:to_binary failed --- no_error_log [error] -=== TEST 9: metamethods checks arg + + +=== TEST 12: metamethods checks arg --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { - local a, err = require("resty.openssl.bn").new(23578164761333) - if err then - ngx.log(ngx.ERR, err) - return - end - local b, err = require("resty.openssl.bn").new(2478652) - if err then - ngx.log(ngx.ERR, err) - return - end + local a = myassert(require("resty.openssl.bn").new(23578164761333)) + local b = myassert(require("resty.openssl.bn").new(2478652)) local pok, perr = pcall(function() return a + "233" end) ngx.say(perr) local pok, perr = pcall(function() return "233" - a end) @@ -291,22 +304,16 @@ bn:to_binary failed --- no_error_log [error] -=== TEST 10: add, sub, mul, div mod + + +=== TEST 13: add, sub, mul, div mod --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { local bn = require("resty.openssl.bn") - local a, err = bn.new(23578164761333) - if err then - ngx.log(ngx.ERR, err) - return - end - local b, err = bn.new(2478652) - if err then - ngx.log(ngx.ERR, err) - return - end + local a = myassert(bn.new(23578164761333)) + local b = myassert(bn.new(2478652)) ngx.say(tostring(a+b)) ngx.say(tostring(a-b)) ngx.say(tostring(a*b)) @@ -336,22 +343,16 @@ bn:to_binary failed --- no_error_log [error] -=== TEST 11: sqr, exp + + +=== TEST 14: sqr, exp --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { local bn = require("resty.openssl.bn") - local a, err = bn.new(23578164761333) - if err then - ngx.log(ngx.ERR, err) - return - end - local b, err = bn.new(97) - if err then - ngx.log(ngx.ERR, err) - return - end + local a = myassert(bn.new(23578164761333)) + local b = myassert(bn.new(97)) ngx.say(tostring(a:sqr())) ngx.say(tostring(a:exp(2))) ngx.say(tostring(a:pow(2))) @@ -377,22 +378,16 @@ bn:to_binary failed --- no_error_log [error] -=== TEST 12: gcd + + +=== TEST 15: gcd --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { local bn = require("resty.openssl.bn") - local a, err = bn.new(23578164761333) - if err then - ngx.log(ngx.ERR, err) - return - end - local b, err = bn.new(97) - if err then - ngx.log(ngx.ERR, err) - return - end + local a = myassert(bn.new(23578164761333)) + local b = myassert(bn.new(97)) ngx.say(tostring(a:gcd(b))) ngx.say(tostring(bn.gcd(a, b))) ngx.say(tostring(bn.gcd(a, 97))) @@ -410,17 +405,15 @@ bn:to_binary failed --- no_error_log [error] -=== TEST 13: lshift, rshift + + +=== TEST 16: lshift, rshift --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { local bn = require("resty.openssl.bn") - local a, err = bn.new(23578164761333) - if err then - ngx.log(ngx.ERR, err) - return - end + local a = myassert(bn.new(23578164761333)) ngx.say(tostring(a:lshift(2))) ngx.say(tostring(a:rshift(2))) } @@ -434,22 +427,16 @@ bn:to_binary failed --- no_error_log [error] -=== TEST 14: comparasion + + +=== TEST 17: comparasion --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { local bn = require("resty.openssl.bn") - local a, err = bn.new(23578164761333) - if err then - ngx.log(ngx.ERR, err) - return - end - local b, err = bn.new(97) - if err then - ngx.log(ngx.ERR, err) - return - end + local a = myassert(bn.new(23578164761333)) + local b = myassert(bn.new(97)) ngx.say(tostring(a == b)) ngx.say(tostring(a ~= b)) ngx.say(tostring(a >= b)) @@ -485,7 +472,9 @@ true --- no_error_log [error] -=== TEST 15: is_one, is_zero, is_odd, is_word + + +=== TEST 18: is_one, is_zero, is_odd, is_word --- http_config eval: $::HttpConfig --- config location =/t { @@ -516,7 +505,9 @@ false --- no_error_log [error] -=== TEST 16: is_prime + + +=== TEST 19: is_prime --- http_config eval: $::HttpConfig --- config location =/t { @@ -539,27 +530,17 @@ true --- no_error_log [error] -=== TEST 17: mod_add, mod_sub, mod_mul, mul_exp, mul_sqr mod + + +=== TEST 20: mod_add, mod_sub, mod_mul, mul_exp, mul_sqr mod --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { local bn = require("resty.openssl.bn") - local a, err = bn.new(23578164761333) - if err then - ngx.log(ngx.ERR, err) - return - end - local b, err = bn.new(2478652) - if err then - ngx.log(ngx.ERR, err) - return - end - local m, err = bn.new(65537) - if err then - ngx.log(ngx.ERR, err) - return - end + local a = myassert(bn.new(23578164761333)) + local b = myassert(bn.new(2478652)) + local m = myassert(bn.new(65537)) ngx.say(tostring(a:mod_add(b, m))) ngx.say(tostring(a:mod_sub(b, m))) ngx.say(tostring(a:mod_mul(b, m))) @@ -583,26 +564,20 @@ true --- no_error_log [error] -=== TEST 18: generate_prime + + +=== TEST 21: generate_prime --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { local bn = require("resty.openssl.bn") - local a, err = bn.generate_prime(10, false) - if err then - ngx.log(ngx.ERR, err) - return - end + local a = myassert(bn.generate_prime(10, false)) if not a:is_prime() then ngx.log(ngx.ERR, "not prime") return end - local a, err = bn.generate_prime(10, true) - if err then - ngx.log(ngx.ERR, err) - return - end + local a = myassert(bn.generate_prime(10, true)) if not a:is_prime() then ngx.log(ngx.ERR, "not prime") return @@ -616,4 +591,4 @@ true "ok " --- no_error_log -[error] \ No newline at end of file +[error] diff --git a/t/openssl/cipher.t b/t/openssl/cipher.t index da46e5923..c0e156270 100644 --- a/t/openssl/cipher.t +++ b/t/openssl/cipher.t @@ -22,12 +22,13 @@ our $HttpConfig = qq{ run_tests(); __DATA__ + === TEST 1: Creates cipher correctly --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { - local cipher = myassert(require("resty.openssl.cipher").new("aes-256-cbc")) + local cipher = myassert(require("resty.openssl.cipher").new("aes256")) myassert(cipher:init(string.rep("0", 32), string.rep("0", 16), { is_encrypt = true, @@ -44,6 +45,7 @@ __DATA__ [error] + === TEST 2: Rejects unknown cipher --- http_config eval: $::HttpConfig --- config @@ -60,12 +62,14 @@ __DATA__ --- no_error_log [error] + + === TEST 3: Unintialized ctx throw errors --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { - local cipher = myassert(require("resty.openssl.cipher").new("aes-256-cbc")) + local cipher = myassert(require("resty.openssl.cipher").new("aes256")) local s, err = cipher:update("1") ngx.say(err) @@ -82,12 +86,14 @@ cipher:update: cipher not initalized, call cipher:init first --- no_error_log [error] + + === TEST 4: Encrypt --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { - local cipher = myassert(require("resty.openssl.cipher").new("aes-256-cbc")) + local cipher = myassert(require("resty.openssl.cipher").new("aes256")) local s = myassert(cipher:encrypt(string.rep("0", 32), string.rep("0", 16), '1')) @@ -101,12 +107,14 @@ cipher:update: cipher not initalized, call cipher:init first --- no_error_log [error] + + === TEST 5: Encrypt no padding --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { - local cipher = myassert(require("resty.openssl.cipher").new("aes-256-cbc")) + local cipher = myassert(require("resty.openssl.cipher").new("aes256")) local s, err = cipher:encrypt(string.rep("0", 32), string.rep("0", 16), '1', true) ngx.say(s) @@ -122,17 +130,19 @@ cipher:update: cipher not initalized, call cipher:init first GET /t --- response_body_like eval "nil -.+(?:data not multiple of block length|wrong final block length|DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH) +.+(?:data not multiple of block length|wrong final block length).* VhGyRCcMvlAgUjTYrqiWpg==" --- no_error_log [error] + + === TEST 6: Decrypt --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { - local cipher = myassert(require("resty.openssl.cipher").new("aes-256-cbc")) + local cipher = myassert(require("resty.openssl.cipher").new("aes256")) local s = myassert(cipher:decrypt(string.rep("0", 32), string.rep("0", 16), ngx.decode_base64("VhGyRCcMvlAgUjTYrqiWpg=="))) @@ -147,12 +157,14 @@ VhGyRCcMvlAgUjTYrqiWpg==" --- no_error_log [error] + + === TEST 7: Decrypt no padding --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { - local cipher = myassert(require("resty.openssl.cipher").new("aes-256-cbc")) + local cipher = myassert(require("resty.openssl.cipher").new("aes256")) local s = myassert(cipher:decrypt(string.rep("0", 32), string.rep("0", 16), ngx.decode_base64("VhGyRCcMvlAgUjTYrqiWpg=="), true)) @@ -167,12 +179,14 @@ VhGyRCcMvlAgUjTYrqiWpg==" --- no_error_log [error] + + === TEST 8: Encrypt streaming --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { - local cipher = myassert(require("resty.openssl.cipher").new("aes-256-cbc")) + local cipher = myassert(require("resty.openssl.cipher").new("aes256")) local ok = myassert(cipher:init(string.rep("0", 32), string.rep("0", 16), { is_encrypt = true, @@ -209,12 +223,14 @@ dtpklHxY9IbgmSw84+2XMr0Vy/S1392+rvu0A3GW1Wo= --- no_error_log [error] + + === TEST 9: Decrypt streaming --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { - local cipher = myassert(require("resty.openssl.cipher").new("aes-256-cbc")) + local cipher = myassert(require("resty.openssl.cipher").new("aes256")) local ok = myassert(cipher:init(string.rep("0", 32), string.rep("0", 16), { is_encrypt = false, @@ -253,7 +269,7 @@ nothing hiabcdefghiabcde fghiabcdefghiabc nothing -.+(wrong final block length|WRONG_FINAL_BLOCK_LENGTH) +.+wrong final block length.* nil final defghi @@ -262,6 +278,7 @@ defghi [error] + === TEST 10: Derive key and iv --- http_config eval: $::HttpConfig --- config @@ -273,9 +290,9 @@ defghi end)) end - local cipher = myassert(require("resty.openssl.cipher").new("aes-256-cbc")) + local cipher = myassert(require("resty.openssl.cipher").new("aes256")) - -- openssl enc -aes-256-cbc -pass pass:xxx -S 797979 -P -md md5 + -- openssl enc -aes256 -pass pass:xxx -S 797979 -P -md md5 local key, iv = cipher:derive("xxx", "yyy", 1, "md5") ngx.say(key:tohex()) @@ -300,6 +317,8 @@ no iv --- no_error_log [error] + + === TEST 11: Derive key and iv: salt, count and md is optional --- http_config eval: $::HttpConfig --- config @@ -311,9 +330,9 @@ no iv end)) end - local cipher = myassert(require("resty.openssl.cipher").new("aes-256-cbc")) + local cipher = myassert(require("resty.openssl.cipher").new("aes256")) - -- openssl enc -aes-256-cbc -pass pass:xxx -nosalt -P -md sha1 + -- openssl enc -aes256 -pass pass:xxx -nosalt -P -md sha1 local key, iv = cipher:derive("xxx") ngx.say(key:tohex()) @@ -329,6 +348,8 @@ no iv --- no_error_log [error] + + === TEST 12: AEAD modes --- http_config eval: $::HttpConfig --- config @@ -368,6 +389,8 @@ nil --- no_error_log [error] + + === TEST 13: Returns provider --- http_config eval: $::HttpConfig --- config @@ -390,6 +413,8 @@ default --- no_error_log [error] + + === TEST 14: Returns gettable, settable params --- http_config eval: $::HttpConfig --- config @@ -409,11 +434,13 @@ default --- request GET /t --- response_body_like -.+ivlen.+ -.+padding.+ +.+ivlen.* +.+padding.* --- no_error_log [error] + + === TEST 15: Get params, set params --- http_config eval: $::HttpConfig --- config @@ -464,6 +491,7 @@ nil [error] + === TEST 16: Update with segements larger than 1024 --- http_config eval: $::HttpConfig --- config diff --git a/t/openssl/ctx.t b/t/openssl/ctx.t index 8a1c29bc5..27e10287d 100644 --- a/t/openssl/ctx.t +++ b/t/openssl/ctx.t @@ -22,6 +22,7 @@ our $HttpConfig = qq{ run_tests(); __DATA__ + === TEST 1: Can create a ctx in ngx.ctx --- http_config eval: $::HttpConfig --- config @@ -40,6 +41,7 @@ __DATA__ [error] + === TEST 2: Can create a ctx in global namespace --- http_config eval: $::HttpConfig --- config @@ -58,6 +60,7 @@ __DATA__ [error] + === TEST 3: Can free ctx in ngx.ctx --- http_config eval: $::HttpConfig --- config @@ -77,6 +80,7 @@ __DATA__ [error] + === TEST 4: Can free ctx in global namespace --- http_config eval: $::HttpConfig --- config diff --git a/t/openssl/digest.t b/t/openssl/digest.t index ab086041f..372dd585a 100644 --- a/t/openssl/digest.t +++ b/t/openssl/digest.t @@ -22,6 +22,7 @@ our $HttpConfig = qq{ run_tests(); __DATA__ + === TEST 1: Calculate digest correctly --- http_config eval: $::HttpConfig --- config @@ -40,6 +41,8 @@ __DATA__ --- no_error_log [error] + + === TEST 2: Update accepts vardiac args --- http_config eval: $::HttpConfig --- config @@ -58,6 +61,8 @@ __DATA__ --- no_error_log [error] + + === TEST 3: Final accepts optional arg --- http_config eval: $::HttpConfig --- config @@ -76,6 +81,8 @@ __DATA__ --- no_error_log [error] + + === TEST 4: Rejects unknown hash --- http_config eval: $::HttpConfig --- config @@ -92,6 +99,8 @@ __DATA__ --- no_error_log [error] + + === TEST 5: Can be reused --- http_config eval: $::HttpConfig --- config @@ -116,6 +125,8 @@ __DATA__ --- no_error_log [error] + + === TEST 6: Returns provider --- http_config eval: $::HttpConfig --- config @@ -138,6 +149,8 @@ default --- no_error_log [error] + + === TEST 7: Returns gettable, settable params --- http_config eval: $::HttpConfig --- config @@ -162,6 +175,8 @@ default --- no_error_log [error] + + === TEST 8: Get params, set params --- http_config eval: $::HttpConfig --- config @@ -177,4 +192,4 @@ default "skipped " --- no_error_log -[error] \ No newline at end of file +[error] diff --git a/t/openssl/err.t b/t/openssl/err.t index 4da69bca5..a84cd9d75 100644 --- a/t/openssl/err.t +++ b/t/openssl/err.t @@ -21,6 +21,7 @@ our $HttpConfig = qq{ run_tests(); __DATA__ + === TEST 1: Don't cry if there's no error --- http_config eval: $::HttpConfig --- config diff --git a/t/openssl/helper.lua b/t/openssl/helper.lua index 42e1ef281..f2f31330c 100644 --- a/t/openssl/helper.lua +++ b/t/openssl/helper.lua @@ -51,7 +51,7 @@ local function to_hex(bin) if err then error(err) end - return hex:upper() + return hex end local function myassert(...) diff --git a/t/openssl/hmac.t b/t/openssl/hmac.t index 0c5cf40b8..55483df81 100644 --- a/t/openssl/hmac.t +++ b/t/openssl/hmac.t @@ -22,6 +22,7 @@ our $HttpConfig = qq{ run_tests(); __DATA__ + === TEST 1: Calculate hmac correctly --- http_config eval: $::HttpConfig --- config @@ -40,6 +41,8 @@ __DATA__ --- no_error_log [error] + + === TEST 2: Update accepts vardiac args --- http_config eval: $::HttpConfig --- config @@ -58,6 +61,8 @@ __DATA__ --- no_error_log [error] + + === TEST 3: Final accepts optional arg --- http_config eval: $::HttpConfig --- config @@ -76,6 +81,8 @@ __DATA__ --- no_error_log [error] + + === TEST 4: Rejects unknown hash --- http_config eval: $::HttpConfig --- config @@ -93,6 +100,7 @@ __DATA__ [error] + === TEST 5: Can be reused --- http_config eval: $::HttpConfig --- config @@ -115,4 +123,4 @@ __DATA__ kwUMjYrP0BSJb8cIJvWYoiM1Kc4mQxZOTwSiTTLRhDM= " --- no_error_log -[error] \ No newline at end of file +[error] diff --git a/t/openssl/kdf.t b/t/openssl/kdf.t index 516768343..06b800287 100644 --- a/t/openssl/kdf.t +++ b/t/openssl/kdf.t @@ -22,6 +22,7 @@ our $HttpConfig = qq{ run_tests(); __DATA__ + === TEST 1: kdf: invalid args are checked --- http_config eval: $::HttpConfig --- config @@ -66,6 +67,7 @@ kdf.derive: unknown type 19823718236128632 [error] + === TEST 2: PBKDF2 --- http_config eval: $::HttpConfig --- config @@ -92,6 +94,7 @@ kdf.derive: unknown type 19823718236128632 [error] + === TEST 3: PBKDF2, optional args --- http_config eval: $::HttpConfig --- config @@ -114,6 +117,7 @@ kdf.derive: unknown type 19823718236128632 [error] + === TEST 4: HKDF --- http_config eval: $::HttpConfig --- config @@ -141,6 +145,7 @@ kdf.derive: unknown type 19823718236128632 [error] + === TEST 5: HKDF, optional arg --- http_config eval: $::HttpConfig --- config @@ -178,6 +183,7 @@ W/tSxFnNsHIYwXa13eybYhW9W3Y= [error] + === TEST 6: TLS1-PRF --- http_config eval: $::HttpConfig --- config @@ -203,6 +209,7 @@ W/tSxFnNsHIYwXa13eybYhW9W3Y= [error] + === TEST 7: TLS1-PRF, optional arg --- http_config eval: $::HttpConfig --- config @@ -227,6 +234,7 @@ W/tSxFnNsHIYwXa13eybYhW9W3Y= [error] + === TEST 8: scrypt --- http_config eval: $::HttpConfig --- config @@ -252,6 +260,8 @@ W/tSxFnNsHIYwXa13eybYhW9W3Y= --- no_error_log [error] + + === TEST 9: EVP_KDF API: new --- http_config eval: $::HttpConfig --- config @@ -277,6 +287,8 @@ W/tSxFnNsHIYwXa13eybYhW9W3Y= --- no_error_log [error] + + === TEST 10: EVP_KDF API: Returns provider --- http_config eval: $::HttpConfig --- config @@ -300,6 +312,7 @@ default [error] + === TEST 11: EVP_KDF API: derive --- http_config eval: $::HttpConfig --- config @@ -327,6 +340,8 @@ cDRFLQ7NWt+AP4i0TdBzog== --- no_error_log [error] + + === TEST 12: EVP_KDF API: Returns gettable, settable params --- http_config eval: $::HttpConfig --- config @@ -351,6 +366,8 @@ cDRFLQ7NWt+AP4i0TdBzog== --- no_error_log [error] + + === TEST 13: EVP_KDF API: Get params, set params --- http_config eval: $::HttpConfig --- config @@ -384,6 +401,8 @@ cDRFLQ7NWt+AP4i0TdBzog== --- no_error_log [error] + + === TEST 14: EVP_KDF API: reset --- http_config eval: $::HttpConfig --- config @@ -421,7 +440,7 @@ cDRFLQ7NWt+AP4i0TdBzog== --- request GET /t --- response_body_like -.+missing salt +.+missing salt.* cDRFLQ7NWt\+AP4i0TdBzog== --- no_error_log [error] diff --git a/t/openssl/mac.t b/t/openssl/mac.t index b3cddf10a..b78d398b8 100644 --- a/t/openssl/mac.t +++ b/t/openssl/mac.t @@ -22,6 +22,7 @@ our $HttpConfig = qq{ run_tests(); __DATA__ + === TEST 1: Calculate mac correctly --- http_config eval: $::HttpConfig --- config @@ -45,6 +46,8 @@ __DATA__ --- no_error_log [error] + + === TEST 2: Update accepts vardiac args --- http_config eval: $::HttpConfig --- config @@ -68,6 +71,8 @@ __DATA__ --- no_error_log [error] + + === TEST 3: Final accepts optional arg --- http_config eval: $::HttpConfig --- config @@ -91,6 +96,8 @@ __DATA__ --- no_error_log [error] + + === TEST 4: Rejects unknown hash --- http_config eval: $::HttpConfig --- config @@ -111,6 +118,8 @@ __DATA__ --- no_error_log [error] + + === TEST 5: Returns provider --- http_config eval: $::HttpConfig --- config @@ -133,6 +142,8 @@ default --- no_error_log [error] + + === TEST 6: Returns gettable, settable params --- http_config eval: $::HttpConfig --- config @@ -157,6 +168,8 @@ default --- no_error_log [error] + + === TEST 7: Get params, set params --- http_config eval: $::HttpConfig --- config diff --git a/t/openssl/objects.t b/t/openssl/objects.t index cec5fb8fa..257728e59 100644 --- a/t/openssl/objects.t +++ b/t/openssl/objects.t @@ -22,6 +22,7 @@ our $HttpConfig = qq{ run_tests(); __DATA__ + === TEST 1: Convert nid to table --- http_config eval: $::HttpConfig --- config @@ -39,6 +40,7 @@ __DATA__ [error] + === TEST 2: Convert txt to nid --- http_config eval: $::HttpConfig --- config @@ -64,6 +66,8 @@ __DATA__ --- no_error_log [error] + + === TEST 3: Convert sigid to nid --- http_config eval: $::HttpConfig --- config @@ -78,4 +82,4 @@ __DATA__ --- response_body eval 673 --- no_error_log -[error] \ No newline at end of file +[error] diff --git a/t/openssl/param.t b/t/openssl/param.t index f85c44200..2c7fb95ee 100644 --- a/t/openssl/param.t +++ b/t/openssl/param.t @@ -22,6 +22,7 @@ our $HttpConfig = qq{ run_tests(); __DATA__ + === TEST 1: Construct --- http_config eval: $::HttpConfig --- config diff --git a/t/openssl/pkcs12.t b/t/openssl/pkcs12.t index 4acedef5f..a1d4afd32 100644 --- a/t/openssl/pkcs12.t +++ b/t/openssl/pkcs12.t @@ -23,6 +23,7 @@ our $HttpConfig = qq{ run_tests(); __DATA__ + === TEST 1: Loads password protected pkcs12 --- http_config eval: $::HttpConfig --- config @@ -39,8 +40,8 @@ __DATA__ local r = myassert(pkcs12.decode(pp, "badssl.com")) - ngx.say(r.key:get_parameters().d:to_hex():upper()) - ngx.say(r.cert:get_serial_number():to_hex():upper()) + ngx.say(r.key:get_parameters().d:to_hex()) + ngx.say(r.cert:get_serial_number():to_hex()) } } --- request @@ -51,6 +52,8 @@ __DATA__ --- no_error_log [error] + + === TEST 2: Errors on bad password --- http_config eval: $::HttpConfig --- config @@ -78,13 +81,15 @@ __DATA__ GET /t --- response_body_like eval 'true -pkcs12.decode.+(mac verify failure|INCORRECT_PASSWORD) +pkcs12.decode.+mac verify failure.* true -pkcs12.decode.+(mac verify failure|INCORRECT_PASSWORD) +pkcs12.decode.+mac verify failure.* ' --- no_error_log [error] + + === TEST 3: Creates pkcs12 --- http_config eval: $::HttpConfig --- config @@ -96,7 +101,7 @@ pkcs12.decode.+(mac verify failure|INCORRECT_PASSWORD) end local pkcs12 = require "resty.openssl.pkcs12" - local cert, key = require("helper").create_self_signed({ type = 'EC', curve = "prime256v1" }) + local cert, key = require("helper").create_self_signed({ type = 'EC' }) local x509 = require("resty.openssl.x509") local ca1 = myassert(x509.new(io.open("t/fixtures/GlobalSign.pem"):read("*a"))) local ca2 = myassert(x509.new(io.open("t/fixtures/GlobalSign_sub.pem"):read("*a"))) @@ -141,6 +146,8 @@ pkcs12.decode.+(mac verify failure|INCORRECT_PASSWORD) --- no_error_log [error] + + === TEST 4: Uses empty string password when omitted --- http_config eval: $::HttpConfig --- config @@ -152,7 +159,7 @@ pkcs12.decode.+(mac verify failure|INCORRECT_PASSWORD) end local pkcs12 = require "resty.openssl.pkcs12" - local cert, key = require("helper").create_self_signed({ type = 'EC', curve = "prime256v1" }) + local cert, key = require("helper").create_self_signed({ type = 'EC' }) local x509 = require("resty.openssl.x509") local ca1 = myassert(x509.new(io.open("t/fixtures/GlobalSign.pem"):read("*a"))) local ca2 = myassert(x509.new(io.open("t/fixtures/GlobalSign_sub.pem"):read("*a"))) @@ -165,8 +172,8 @@ pkcs12.decode.+(mac verify failure|INCORRECT_PASSWORD) })) local r = myassert(pkcs12.decode(p12, nil)) - ngx.say(#r.key:get_parameters().x:to_hex():upper()) - ngx.say(r.cert:get_serial_number():to_hex():upper()) + ngx.say(#r.key:get_parameters().x:to_hex()) + ngx.say(r.cert:get_serial_number():to_hex()) ngx.say(#r.cacerts) ngx.say(r.friendly_name) -- same as empty string @@ -181,16 +188,18 @@ pkcs12.decode.+(mac verify failure|INCORRECT_PASSWORD) --- request GET /t --- response_body_like eval -'6\d +'4\d 0 2 myname true -pkcs12.decode.+(mac verify failure|INCORRECT_PASSWORD) +pkcs12.decode.+mac verify failure.* ' --- no_error_log [error] + + === TEST 5: Check cert and key mismatch --- http_config eval: $::HttpConfig --- config @@ -202,8 +211,8 @@ pkcs12.decode.+(mac verify failure|INCORRECT_PASSWORD) end local pkcs12 = require "resty.openssl.pkcs12" - local cert, key = require("helper").create_self_signed({ type = 'EC', curve = "prime256v1" }) - local key2 = require("resty.openssl.pkey").new({ type = 'EC', curve = "prime256v1" }) + local cert, key = require("helper").create_self_signed({ type = 'EC' }) + local key2 = require("resty.openssl.pkey").new({ type = 'EC' }) local r, err = pkcs12.encode({ friendly_name = "myname", @@ -217,11 +226,13 @@ pkcs12.decode.+(mac verify failure|INCORRECT_PASSWORD) --- request GET /t --- response_body_like eval -'true.+(key values mismatch|KEY_VALUES_MISMATCH) +'true.+key values mismatch.* ' --- no_error_log [error] + + === TEST 6: Creates pkcs12 with newer algorithm --- http_config eval: $::HttpConfig --- config diff --git a/t/openssl/pkey.t b/t/openssl/pkey.t index 5c425b8d1..7832a6435 100644 --- a/t/openssl/pkey.t +++ b/t/openssl/pkey.t @@ -25,7 +25,8 @@ no_long_string(); run_tests(); __DATA__ -=== TEST 1: Generates RSA key by default + +=== TEST 1: keygen: Generates RSA key by default --- http_config eval: $::HttpConfig --- config location =/t { @@ -41,7 +42,9 @@ __DATA__ --- no_error_log [error] -=== TEST 2: Generates and loads RSA key + + +=== TEST 2: keygen: Generates and loads RSA key --- http_config eval: $::HttpConfig --- config location =/t { @@ -65,7 +68,9 @@ true" --- no_error_log [error] -=== TEST 3: Generates and loads EC key explictly + + +=== TEST 3: keygen: Generates and loads EC key explictly --- http_config eval: $::HttpConfig --- config location =/t { @@ -89,7 +94,9 @@ true" --- no_error_log [error] -=== TEST 4: Generates and loads Ed25519 key explictly + + +=== TEST 4: keygen: Generates and loads Ed25519 key explictly --- http_config eval: $::HttpConfig --- config location =/t { @@ -112,7 +119,9 @@ true" --- no_error_log [error] -=== TEST 5: Generates and loads DH key explictly + + +=== TEST 5: keygen: Generates and loads DH key explictly --- http_config eval: $::HttpConfig --- config location =/t { @@ -137,7 +146,9 @@ true" --- no_error_log [error] -=== TEST 6: Uses DH predefined groups + + +=== TEST 6: keygen: Uses DH predefined groups --- http_config eval: $::HttpConfig --- config location =/t { @@ -161,7 +172,9 @@ true" --- no_error_log [error] -=== TEST 7: Rejects invalid arg + + +=== TEST 7: keygen: Rejects invalid arg --- http_config eval: $::HttpConfig --- config location =/t { @@ -182,7 +195,108 @@ pkey.new:load_key: .+ --- no_error_log [error] -=== TEST 8: Loads encrypted PEM pkey with passphrase + + +=== TEST 8: keygen: Keygen and paramgen with ctrl str +--- http_config eval: $::HttpConfig +--- config + location =/t { + content_by_lua_block { + local p_384 = myassert(require("resty.openssl.pkey").new({ + type = "EC", + "ec_paramgen_curve:secp384r1", + })) + ngx.say(myassert(p_384:get_parameters()).group) + + local _, err = myassert(require("resty.openssl.pkey").paramgen({ + type = "EC", + "ec_paramgen_curve:secp384r1", + })) + ngx.say(err) + } + } +--- request + GET /t +--- response_body +715 +nil +--- no_error_log +[error] + + + +=== TEST 9: paramgen: Outpus DH and EC params +--- http_config eval: $::HttpConfig +--- config + location =/t { + content_by_lua_block { + local pkey = require("resty.openssl.pkey") + ngx.say(myassert(pkey.paramgen({ + type = 'DH', + group = "dh_1024_160", + }))) + ngx.say(myassert(pkey.paramgen({ + type = "EC", + curve = "prime256v1", + }))) + collectgarbage() + } + } +--- request + GET /t +--- response_body_like eval +"-----BEGIN DH PARAMETERS----- +.+ +-----BEGIN EC PARAMETERS-----" +--- no_error_log +[error] + + + +=== TEST 10: paramgen: Load parameters for keygen +--- http_config eval: $::HttpConfig +--- config + location =/t { + content_by_lua_block { + local pem = myassert(require("resty.openssl.pkey").paramgen({ + type = "DH", + group = "dh_1024_160", + })) + + local p = myassert(require("resty.openssl.pkey").new({ + type = "DH", + param = pem, + })) + + ngx.say(myassert(p:get_parameters().p:to_hex())) + + local pem = myassert(require("resty.openssl.pkey").paramgen({ + type = "EC", + curve = "prime192v1", + })) + + local p = myassert(require("resty.openssl.pkey").new({ + type = "EC", + param = pem, + })) + + ngx.say(myassert(p:get_parameters().group)) + + collectgarbage() + } + } +--- request + GET /t +--- response_body_like eval +"B10B8F96A080E01DDE92DE5EAE5D54EC52C99FBCFB06A3C69A6A9DCA52D23B616073E28675A23D189838EF1E2EE652C013ECB4AEA906112324975C3CD49B83BFACCBDD7D90C4BD7098488E9C219A73724EFFD6FAE5644738FAA31A4FF55BCCC0A151AF5F0DC8B4BD45BF37DF365C1A65E68CFDA76D4DA708DF1FB2BC2E4A4371 +409 +" +--- no_error_log +[error] + + + +=== TEST 11: load: Loads encrypted PEM pkey with passphrase --- http_config eval: $::HttpConfig --- config location =/t { @@ -206,13 +320,15 @@ pkey.new:load_key: .+ --- request GET /t --- response_body_like eval -"pkey.new.+(?:bad decrypt|failed|BAD_DECRYPT) +"pkey.new.+(?:bad decrypt|failed).* ok " --- no_error_log [error] -=== TEST 9: Loads encrypted PEM pkey with passphrase callback + + +=== TEST 12: load: Loads encrypted PEM pkey with passphrase callback --- http_config eval: $::HttpConfig --- config location =/t { @@ -240,735 +356,15 @@ ok --- request GET /t --- response_body_like eval -"pkey.new.+(?:bad decrypt|failed|BAD_DECRYPT) +"pkey.new.+(?:bad decrypt|failed).* ok " --- no_error_log [error] -=== TEST 10: Loads DER format ---- http_config eval: $::HttpConfig ---- config - location =/t { - content_by_lua_block { - local pkey = require("resty.openssl.pkey") - local p1 = myassert(pkey.new()) - local pem = p1:to_PEM('private') - local der = myassert(p1:tostring('private', 'DER')) - local p2 = myassert(pkey.new(der)) - ngx.print(p2 and pem == p2:to_PEM('private')) - } - } ---- request - GET /t ---- response_body eval -"true" ---- no_error_log -[error] - -=== TEST 11: Outputs DER and JWK ---- http_config eval: $::HttpConfig ---- config - location =/t { - content_by_lua_block { - local p = myassert(require("resty.openssl.pkey").new({ - type = "EC", - curve = 'prime256v1', - })) - local t = myassert(p:tostring('private', "PEM")) - ngx.say(t) - - local t = myassert(p:tostring('private', "DER")) - ngx.say(#t) - - local t = myassert(p:tostring('private', "JWK")) - ngx.say(t) - } - } ---- request - GET /t ---- response_body_like eval -"-----BEGIN PRIVATE KEY----- -.+ ------END PRIVATE KEY----- - -(121|138|364) -.+kid.+" ---- no_error_log -[error] - -=== TEST 12: Outputs public key ---- http_config eval: $::HttpConfig ---- config - location =/t { - content_by_lua_block { - local p = myassert(require("resty.openssl.pkey").new()) - ngx.say(p:to_PEM()) - } - } ---- request - GET /t ---- response_body_like eval -"-----BEGIN PUBLIC KEY-----" ---- no_error_log -[error] - -=== TEST 13: Extracts RSA parameters ---- http_config eval: $::HttpConfig ---- config - location =/t { - content_by_lua_block { - local p = myassert(require("resty.openssl.pkey").new({ - exp = 65537, - })) - - local params = myassert(p:get_parameters()) - - for _, k in ipairs(require("resty.openssl.rsa").params) do - local b = myassert(params[k]:to_hex():upper()) - ngx.say(b) - end - local got = params.dne - ngx.say(got) - } - } ---- request - GET /t ---- response_body_like eval -"[A-F0-9]+ -[A-F0-9]+ -[A-F0-9]+ -[A-F0-9]+ -[A-F0-9]+ -[A-F0-9]+ -[A-F0-9]+ -[A-F0-9]+ -nil -" ---- no_error_log -[error] - -=== TEST 14: Extracts EC parameters ---- http_config eval: $::HttpConfig ---- config - location =/t { - content_by_lua_block { - local p = myassert(require("resty.openssl.pkey").new({ - type = "EC", - curve = "prime256v1", - })) - - local params = myassert(p:get_parameters()) - - local group = params["group"] - ngx.say(group) - for _, k in ipairs(require("resty.openssl.ec").params) do - if k ~= "group" then - local b = myassert(params[k]:to_hex():upper()) - - ngx.say(b) - end - end - local got = params.dne - ngx.say(got) - } - } ---- request - GET /t ---- response_body_like eval -"415 -[A-F0-9]{1,130} -[A-F0-9]{1,64} -[A-F0-9]{1,64} -[A-F0-9]{1,64} -nil -" ---- no_error_log -[error] - -=== TEST 15: Extracts Ed25519 parameters ---- http_config eval: $::HttpConfig ---- config - location =/t { - content_by_lua_block { - local p = myassert(require("resty.openssl.pkey").new({ - type = "Ed25519", - })) - - local params = myassert(p:get_parameters()) - - ngx.say(#params.private) - ngx.say(#params.public) - } - } ---- request - GET /t ---- response_body_like eval -"32 -32 -" ---- no_error_log -[error] - -=== TEST 16: Extracts DH parameters ---- http_config eval: $::HttpConfig ---- config - location =/t { - content_by_lua_block { - local p = myassert(require("resty.openssl.pkey").new({ - type = "DH", - group = "dh_1024_160", - })) - - local params = myassert(p:get_parameters()) - - ngx.say(params.p:to_hex():upper()) - ngx.say(params.g:to_hex():upper()) - ngx.say(params.private:to_hex():upper()) - ngx.say(params.public:to_hex():upper()) - } - } ---- request - GET /t ---- response_body_like eval -"B10B8F96A080E01DDE92DE5EAE5D54EC52C99FBCFB06A3C69A6A9DCA52D23B616073E28675A23D189838EF1E2EE652C013ECB4AEA906112324975C3CD49B83BFACCBDD7D90C4BD7098488E9C219A73724EFFD6FAE5644738FAA31A4FF55BCCC0A151AF5F0DC8B4BD45BF37DF365C1A65E68CFDA76D4DA708DF1FB2BC2E4A4371 -A4D1CBD5C3FD34126765A442EFB99905F8104DD258AC507FD6406CFF14266D31266FEA1E5C41564B777E690F5504F213160217B4B01B886A5E91547F9E2749F4D7FBD7D3B9A92EE1909D0D2263F80A76A6A24C087A091F531DBF0A0169B6A28AD662A4D18E73AFA32D779D5918D08BC8858F4DCEF97C2A24855E6EEB22B3B2E5 -[A-F0-9]+ -[A-F0-9]+ -" ---- no_error_log -[error] - -=== TEST 17: Encrypt and decrypt ---- http_config eval: $::HttpConfig ---- config - location =/t { - content_by_lua_block { - local privkey = myassert(require("resty.openssl.pkey").new()) - if err then - ngx.log(ngx.ERR, err) - return - end - local pubkey = myassert(require("resty.openssl.pkey").new(assert(privkey:to_PEM("public")))) - - local s = myassert(pubkey:encrypt("23333")) - ngx.say(#s) - - local decrypted = myassert(privkey:decrypt(s)) - ngx.say(decrypted) - } - } ---- request - GET /t ---- response_body eval -"256 -23333 -" ---- no_error_log -[error] - - -=== TEST 18: Sign and verify ---- http_config eval: $::HttpConfig ---- config - location =/t { - content_by_lua_block { - local p = myassert(require("resty.openssl.pkey").new()) - - local digest = myassert(require("resty.openssl.digest").new("SHA256")) - - myassert(digest:update("🕶️", "+1s")) - - local s = myassert(p:sign(digest)) - ngx.say(#s) - - local v = myassert(p:verify(s, digest)) - ngx.say(v) - } - } ---- request - GET /t ---- response_body eval -"256 -true -" ---- no_error_log -[error] - -=== TEST 19: One shot sign and verify ---- http_config eval: $::HttpConfig ---- config - location =/t { - content_by_lua_block { - -- pureeddsa - local p = myassert(require("resty.openssl.pkey").new({ - type = "Ed25519" - })) - local digest = "23333" - local s = myassert(p:sign(digest)) - ngx.say(#s) - - local v = myassert(p:verify(s, digest)) - ngx.say(v) - - -- uses default md type - local p = myassert(require("resty.openssl.pkey").new({ - type = "RSA" - })) - local digest = "23333" - local s = myassert(p:sign(digest)) - ngx.say(#s) - - local v = myassert(p:verify(s, digest)) - ngx.say(v) - } - } ---- request - GET /t ---- response_body eval -"64 -true -256 -true -" ---- no_error_log -[error] - -=== TEST 20: Error on bad digest or verify parameters ---- http_config eval: $::HttpConfig ---- config - location =/t { - content_by_lua_block { - local p = myassert(require("resty.openssl.pkey").new({ - type = "EC", - curve = "prime256v1", - })) - local s, err = p:sign(false) - ngx.say(err) - local v, err = p:verify("", false) - ngx.say(err) - local v, err = p:verify(false, "1") - ngx.say(err) - } - } ---- request - GET /t ---- response_body eval -"pkey:sign: expect a digest instance or a string at #1 -pkey:verify: expect a digest instance or a string at #2 -pkey:verify: expect a string at #1 -" ---- no_error_log -[error] - -=== TEST 21: Key derivation for EC, X448 and X25519 ---- http_config eval: $::HttpConfig ---- config - location =/t { - content_by_lua_block { - for i, t in ipairs({"EC", "X25519", "X448"}) do - local p = myassert(require("resty.openssl.pkey").new({ - type = t, - curve = t == "EC" and "prime256v1" or nil, - })) - - -- usually the peer key is the pubkey from other key pair - -- we use the same key here just for simplicity - local k = myassert(p:derive(p)) - ngx.say(#k) - ::next:: - end - } - } ---- request - GET /t ---- response_body_like eval -"32 -32 -56" ---- no_error_log -[error] - -=== TEST 22: get key type ---- http_config eval: $::HttpConfig ---- config - location =/t { - content_by_lua_block { - local p, err = myassert(require("resty.openssl.pkey").new({ - type = 'RSA', - })) - ngx.say(encode_sorted_json(p:get_key_type())) - } - } ---- request - GET /t ---- response_body_like eval -'{"id":"1.2.840.113549.1.1.1","ln":"rsaEncryption","nid":6,"sn":"rsaEncryption"}' ---- no_error_log -[error] - -=== TEST 23: Raw sign and recover ---- http_config eval: $::HttpConfig ---- config - location =/t { - content_by_lua_block { - local p = myassert(require("resty.openssl.pkey").new()) - - local s = myassert(p:sign_raw("🕶️")) - ngx.say(#s) - - local v = myassert(p:verify_recover(s)) - ngx.say(v == "🕶️") - } - } ---- request - GET /t ---- response_body eval -"256 -true -" ---- no_error_log -[error] - -=== TEST 24: Streaming sign and one shot sign can cross verify ---- http_config eval: $::HttpConfig ---- config - location =/t { - content_by_lua_block { - local p = myassert(require("resty.openssl.pkey").new()) - local pec = myassert(require("resty.openssl.pkey").new({ - type = "EC", - curve = "prime256v1", - })) - - -- one shot sign RSA, verify with digest instance - local s = myassert(p:sign("🕶️+1s")) - - local digest = myassert(require("resty.openssl.digest").new("SHA256")) - digest:update("🕶️+1s") - local v, err = p:verify(s, digest) - ngx.say(v) - - -- sign with digest RSA, one shot verify - local digest = myassert(require("resty.openssl.digest").new("SHA256")) - digest:update("🕶️+1s") - local s = myassert(p:sign(digest)) - - local v, err = p:verify(s, "🕶️+1s") - ngx.say(v) - - -- one shot sign EC, verify with digest instance - local s = myassert(pec:sign("🕶️+1s")) - - local digest = myassert(require("resty.openssl.digest").new("SHA256")) - digest:update("🕶️+1s") - local v, err = pec:verify(s, digest) - ngx.say(v) - - -- sign with digest EC, one shot verify - local digest = myassert(require("resty.openssl.digest").new("SHA256")) - digest:update("🕶️+1s") - local s = myassert(pec:sign(digest)) - - local v, err = pec:verify(s, "🕶️+1s") - ngx.say(v) - } - } ---- request - GET /t ---- response_body eval -"true -true -true -true -" ---- no_error_log -[error] - -=== TEST 25: Outpus DH and EC params ---- http_config eval: $::HttpConfig ---- config - location =/t { - content_by_lua_block { - local pkey = require("resty.openssl.pkey") - ngx.say(myassert(pkey.paramgen({ - type = 'DH', - group = "dh_1024_160", - }))) - ngx.say(myassert(pkey.paramgen({ - type = "EC", - curve = "prime256v1", - }))) - collectgarbage() - } - } ---- request - GET /t ---- response_body_like eval -"-----BEGIN DH PARAMETERS----- -.+ ------BEGIN EC PARAMETERS-----" ---- no_error_log -[error] - - -=== TEST 26: Set DH parameters ---- http_config eval: $::HttpConfig ---- config - location =/t { - content_by_lua_block { - local p = myassert(require("resty.openssl.pkey").new({ - type = "DH", - group = "dh_1024_160", - })) - - local params1 = myassert(p:get_parameters()) - - local p = myassert(require("resty.openssl.pkey").new({ - type = "DH", - group = "dh_2048_224", - })) - - myassert(p:set_parameters({ - p = params1.p, - g = params1.g, - private = params1.private, - public = params1.public, - })) - - local params = myassert(p:get_parameters()) - - ngx.say(params.p:to_hex():upper()) - ngx.say(params.g:to_hex():upper()) - ngx.say(params.private:to_hex():upper()) - ngx.say(params.public:to_hex():upper()) - - collectgarbage() - } - } ---- request - GET /t ---- response_body_like eval -"B10B8F96A080E01DDE92DE5EAE5D54EC52C99FBCFB06A3C69A6A9DCA52D23B616073E28675A23D189838EF1E2EE652C013ECB4AEA906112324975C3CD49B83BFACCBDD7D90C4BD7098488E9C219A73724EFFD6FAE5644738FAA31A4FF55BCCC0A151AF5F0DC8B4BD45BF37DF365C1A65E68CFDA76D4DA708DF1FB2BC2E4A4371 -A4D1CBD5C3FD34126765A442EFB99905F8104DD258AC507FD6406CFF14266D31266FEA1E5C41564B777E690F5504F213160217B4B01B886A5E91547F9E2749F4D7FBD7D3B9A92EE1909D0D2263F80A76A6A24C087A091F531DBF0A0169B6A28AD662A4D18E73AFA32D779D5918D08BC8858F4DCEF97C2A24855E6EEB22B3B2E5 -[A-F0-9]{1,256} -[A-F0-9]{1,256} -" ---- no_error_log -[error] - -=== TEST 27: Load parameters for keygen ---- http_config eval: $::HttpConfig ---- config - location =/t { - content_by_lua_block { - local pem = myassert(require("resty.openssl.pkey").paramgen({ - type = "DH", - group = "dh_1024_160", - })) - - local p = myassert(require("resty.openssl.pkey").new({ - type = "DH", - param = pem, - })) - - ngx.say(myassert(p:get_parameters().p:to_hex():upper())) - - local pem = myassert(require("resty.openssl.pkey").paramgen({ - type = "EC", - curve = "prime256v1", - })) - - local p = myassert(require("resty.openssl.pkey").new({ - type = "EC", - param = pem, - })) - - ngx.say(myassert(p:get_parameters().group)) - - collectgarbage() - } - } ---- request - GET /t ---- response_body_like eval -"B10B8F96A080E01DDE92DE5EAE5D54EC52C99FBCFB06A3C69A6A9DCA52D23B616073E28675A23D189838EF1E2EE652C013ECB4AEA906112324975C3CD49B83BFACCBDD7D90C4BD7098488E9C219A73724EFFD6FAE5644738FAA31A4FF55BCCC0A151AF5F0DC8B4BD45BF37DF365C1A65E68CFDA76D4DA708DF1FB2BC2E4A4371 -415 -" ---- no_error_log -[error] - -=== TEST 28: Checks if it's private key ---- http_config eval: $::HttpConfig ---- config - location =/t { - content_by_lua_block { - local opts = { - { type = 'RSA', bits = 1024 }, - { type = "EC", curve = "prime256v1" }, - { type = 'DH', group = "dh_1024_160",}, - } - for _, opt in ipairs(opts) do - local priv = myassert(require("resty.openssl.pkey").new(opt)) - - local ok, err = priv:is_private() - if not ok then - ngx.say(opt.type .. ": should be a private key, but returns false: ".. (err or "nil")) - end - - local pem = myassert(priv:to_PEM("public")) - - local pub = myassert(require("resty.openssl.pkey").new(pem)) - - local ok, err = pub:is_private() - if ok then - ngx.say(opt.type .. ": should not be a private key, but returns true: ".. (err or "nil")) - end - end - } - } ---- request - GET /t ---- response_body eval -"" ---- no_error_log -[error] - -=== TEST 29: Checks if it's private key: ecx ---- http_config eval: $::HttpConfig ---- config - location =/t { - content_by_lua_block { - local opts = { - { type = 'Ed25519'}, - } - for _, opt in ipairs(opts) do - local priv = myassert(require("resty.openssl.pkey").new(opt)) - - local ok, err = priv:is_private() - if not ok then - ngx.say(opt.type .. ": should be a private key, but returns false: ".. (err or "nil")) - end - - local pem = myassert(priv:to_PEM("public")) - - local pub = myassert(require("resty.openssl.pkey").new(pem)) - - local ok, err = pub:is_private() - if ok then - ngx.say(opt.type .. ": should not be a private key, but returns true: ".. (err or "nil")) - end - end - } - } ---- request - GET /t ---- response_body eval -"" ---- no_error_log -[error] - -=== TEST 30: Sign/verify with md_alg ---- http_config eval: $::HttpConfig ---- config - location =/t { - content_by_lua_block { - -- uses default md type - local p = myassert(require("resty.openssl.pkey").new({ - type = "RSA" - })) - local digest = "23333" - local s = myassert(p:sign(digest, "sha512")) - ngx.say(#s) - - local ok = myassert(p:verify(s, digest, "sha512")) - ngx.say(ok) - - -- use wrong md type, should not pass - local ok, e = p:verify(s, digest, "sha256") - ngx.say(ok) - local ok, e = p:verify(s, digest, "md5") - ngx.say(ok) - } - } ---- request - GET /t ---- response_body eval -"256 -true -false -false -" ---- no_error_log -[error] - -=== TEST 31: Sign/verify with paddings ---- http_config eval: $::HttpConfig ---- config - location =/t { - content_by_lua_block { - -- uses default md type - - local p = myassert(require("resty.openssl.pkey").new({ - type = "RSA" - })) - local digest = "23333" - local s = myassert(p:sign(digest, md, p.PADDINGS.RSA_PKCS1_PSS_PADDING)) - ngx.say(#s) - - local ok = myassert(p:verify(s, digest, md, p.PADDINGS.RSA_PKCS1_PSS_PADDING)) - ngx.say(ok) - - -- use wrong padding scheme, should not pass - local ok, e = p:verify(s, digest, nil) - if ok ~= false then ngx.say(e) else ngx.say(ok) end - local ok, e = p:verify(s, digest, nil, p.PADDINGS.RSA_PKCS1_PADDING) - if ok ~= false then ngx.say(e) else ngx.say(ok) end - } - } ---- request - GET /t ---- response_body eval -"256 -true -false -false -" ---- no_error_log -[error] - -=== TEST 32: Sign/verify with PSS custom salt_len ---- http_config eval: $::HttpConfig ---- config - location =/t { - content_by_lua_block { - local p = myassert(require("resty.openssl.pkey").new({ - type = "RSA" - })) - local digest = "23333" - local s = myassert(p:sign(digest, nil, p.PADDINGS.RSA_PKCS1_PSS_PADDING, { - pss_saltlen = 64, - })) - ngx.say(#s) - - local ok = myassert(p:verify(s, digest, nil, p.PADDINGS.RSA_PKCS1_PSS_PADDING, { - pss_saltlen = 64, - })) - ngx.say(ok) - } - } ---- request - GET /t ---- response_body eval -"256 -true -" ---- no_error_log -[error] - -=== TEST 33: PEM passphrase_cb won't overflow +=== TEST 13: load: PEM passphrase_cb won't overflow --- http_config eval: $::HttpConfig --- config location =/t { @@ -1033,105 +429,40 @@ true GET /t --- response_body_like eval "errored out with too many callbacks -pkey.new.+(?:bad decrypt|failed|BAD_DECRYPT|no start line|NO_START_LINE|DECODER routines::unsupported) +pkey.new.+(?:bad decrypt|failed|no start line|DECODER routines:OSSL_DECODER_from_bio:unsupported).* ok ok " --- no_error_log [error] -=== TEST 34: Returns provider + + +=== TEST 14: load: Loads DER format --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { - if not require("resty.openssl.version").OPENSSL_3X then - ngx.say("default") - ngx.exit(0) - end - local pkey = require("resty.openssl.pkey") - local p = myassert(pkey.new({ type = "EC" })) - ngx.say(myassert(p:get_provider_name())) - } - } ---- request - GET /t ---- response_body -default ---- no_error_log -[error] + local p1 = myassert(pkey.new()) -=== TEST 35: Returns gettable, settable params ---- http_config eval: $::HttpConfig ---- config - location =/t { - content_by_lua_block { - if not require("resty.openssl.version").OPENSSL_3X then - ngx.say("-bits-\n-encoding-") - ngx.exit(0) - end + local pem = p1:to_PEM('private') + local der = myassert(p1:tostring('private', 'DER')) + local p2 = myassert(pkey.new(der)) - local pkey = require("resty.openssl.pkey") - local p = myassert(pkey.new({ type = "EC" })) - ngx.say(require("cjson").encode(myassert(p:gettable_params()))) - ngx.say(require("cjson").encode(myassert(p:settable_params()))) - } - } ---- request - GET /t ---- response_body_like -.+bits.+ -.+encoding.+ ---- no_error_log -[error] - -=== TEST 36: Get params, set params ---- http_config eval: $::HttpConfig ---- config - location =/t { - content_by_lua_block { - if not require("resty.openssl.version").OPENSSL_3X then - ngx.say("true") - ngx.exit(0) - end - - local pkey = require("resty.openssl.pkey") - local p = myassert(pkey.new({ type = "EC" })) - local priv = myassert(p:get_param("priv", nil, "bn")) - local priv2 = p:get_parameters().private - ngx.say(priv == priv2) - - myassert(p:set_params({["point-format"] = "UNCOMPRESSED"})) + ngx.print(p2 and pem == p2:to_PEM('private')) } } --- request GET /t --- response_body eval -"true -" +"true" --- no_error_log [error] -=== TEST 37: Get default digest type ---- http_config eval: $::HttpConfig ---- config - location =/t { - content_by_lua_block { - local pkey = require("resty.openssl.pkey") - local p = myassert(pkey.new({ type = "EC" })) - local algo = myassert(p:get_default_digest_type()) - ngx.say(require("cjson").encode(algo)) - } - } ---- request - GET /t ---- response_body_like -.+sha256.+ ---- no_error_log -[error] -=== TEST 38: Reads and write pkcs1 rsa key + +=== TEST 15: load: Reads and write pkcs1 rsa key --- http_config eval: $::HttpConfig --- config location =/t { @@ -1179,7 +510,566 @@ true --- no_error_log [error] -=== TEST 39: Sign/verify with binary ecdsa sig + + +=== TEST 16: write: Outputs DER and JWK +--- http_config eval: $::HttpConfig +--- config + location =/t { + content_by_lua_block { + local p = myassert(require("resty.openssl.pkey").new({ + type = "EC", + curve = 'prime256v1', + })) + local t = myassert(p:tostring('private', "PEM")) + ngx.say(t) + + local t = myassert(p:tostring('private', "DER")) + ngx.say(#t) + + local t = myassert(p:tostring('private', "JWK")) + ngx.say(t) + } + } +--- request + GET /t +--- response_body_like eval +"-----BEGIN PRIVATE KEY----- +.+ +-----END PRIVATE KEY----- + +(121|138|364) +.+kid.+" +--- no_error_log +[error] + + + +=== TEST 17: write: Outputs public key +--- http_config eval: $::HttpConfig +--- config + location =/t { + content_by_lua_block { + local p = myassert(require("resty.openssl.pkey").new()) + ngx.say(p:to_PEM()) + } + } +--- request + GET /t +--- response_body_like eval +"-----BEGIN PUBLIC KEY-----" +--- no_error_log +[error] + + + +=== TEST 18: parameters: Extracts RSA parameters +--- http_config eval: $::HttpConfig +--- config + location =/t { + content_by_lua_block { + local p = myassert(require("resty.openssl.pkey").new({ + exp = 65537, + })) + + local params = myassert(p:get_parameters()) + + for _, k in ipairs(require("resty.openssl.rsa").params) do + local b = myassert(params[k]:to_hex()) + ngx.say(b) + end + local got = params.dne + ngx.say(got) + } + } +--- request + GET /t +--- response_body_like eval +"[A-F0-9]+ +[A-F0-9]+ +[A-F0-9]+ +[A-F0-9]+ +[A-F0-9]+ +[A-F0-9]+ +[A-F0-9]+ +[A-F0-9]+ +nil +" +--- no_error_log +[error] + + + +=== TEST 19: parameters: Extracts EC parameters +--- http_config eval: $::HttpConfig +--- config + location =/t { + content_by_lua_block { + local p = myassert(require("resty.openssl.pkey").new({ + type = "EC", + })) + + local params = myassert(p:get_parameters()) + + local group = params["group"] + ngx.say(group) + for _, k in ipairs(require("resty.openssl.ec").params) do + if k ~= "group" then + local b = myassert(params[k]:to_hex()) + + ngx.say(b) + end + end + local got = params.dne + ngx.say(got) + } + } +--- request + GET /t +--- response_body_like eval +"409 +[A-F0-9]{1,98} +[A-F0-9]{1,48} +[A-F0-9]{1,48} +[A-F0-9]{1,48} +nil +" +--- no_error_log +[error] + + + +=== TEST 20: parameters: Extracts Ed25519 parameters +--- http_config eval: $::HttpConfig +--- config + location =/t { + content_by_lua_block { + local p = myassert(require("resty.openssl.pkey").new({ + type = "Ed25519", + })) + + local params = myassert(p:get_parameters()) + + ngx.say(#params.private) + ngx.say(#params.public) + } + } +--- request + GET /t +--- response_body_like eval +"32 +32 +" +--- no_error_log +[error] + + + +=== TEST 21: parameters: Set DH parameters +--- http_config eval: $::HttpConfig +--- config + location =/t { + content_by_lua_block { + local p = myassert(require("resty.openssl.pkey").new({ + type = "DH", + group = "dh_1024_160", + })) + + local params1 = myassert(p:get_parameters()) + + local p = myassert(require("resty.openssl.pkey").new({ + type = "DH", + group = "dh_2048_224", + })) + + myassert(p:set_parameters({ + p = params1.p, + g = params1.g, + private = params1.private, + public = params1.public, + })) + + local params = myassert(p:get_parameters()) + + ngx.say(params.p:to_hex()) + ngx.say(params.g:to_hex()) + ngx.say(params.private:to_hex()) + ngx.say(params.public:to_hex()) + + collectgarbage() + } + } +--- request + GET /t +--- response_body_like eval +"B10B8F96A080E01DDE92DE5EAE5D54EC52C99FBCFB06A3C69A6A9DCA52D23B616073E28675A23D189838EF1E2EE652C013ECB4AEA906112324975C3CD49B83BFACCBDD7D90C4BD7098488E9C219A73724EFFD6FAE5644738FAA31A4FF55BCCC0A151AF5F0DC8B4BD45BF37DF365C1A65E68CFDA76D4DA708DF1FB2BC2E4A4371 +A4D1CBD5C3FD34126765A442EFB99905F8104DD258AC507FD6406CFF14266D31266FEA1E5C41564B777E690F5504F213160217B4B01B886A5E91547F9E2749F4D7FBD7D3B9A92EE1909D0D2263F80A76A6A24C087A091F531DBF0A0169B6A28AD662A4D18E73AFA32D779D5918D08BC8858F4DCEF97C2A24855E6EEB22B3B2E5 +[A-F0-9]{1,256} +[A-F0-9]{1,256} +" +--- no_error_log +[error] + + + +=== TEST 22: encryption: Encrypt and decrypt +--- http_config eval: $::HttpConfig +--- config + location =/t { + content_by_lua_block { + local privkey = myassert(require("resty.openssl.pkey").new()) + if err then + ngx.log(ngx.ERR, err) + return + end + local pubkey = myassert(require("resty.openssl.pkey").new(assert(privkey:to_PEM("public")))) + + local s = myassert(pubkey:encrypt("23333")) + ngx.say(#s) + + local decrypted = myassert(privkey:decrypt(s)) + ngx.say(decrypted) + } + } +--- request + GET /t +--- response_body eval +"256 +23333 +" +--- no_error_log +[error] + + + +=== TEST 23: encryption: Encrypt and decrypt with ctrl str +--- http_config eval: $::HttpConfig +--- config + location =/t { + content_by_lua_block { + local privkey = myassert(require("resty.openssl.pkey").new()) + if err then + ngx.log(ngx.ERR, err) + return + end + local pubkey = myassert(require("resty.openssl.pkey").new(assert(privkey:to_PEM("public")))) + + local s = myassert(pubkey:encrypt("23333", privkey.PADDINGS.RSA_PKCS1_OAEP_PADDING, { + oaep_md = "sha256", + })) + ngx.say(#s) + + local decrypted = myassert(privkey:decrypt(s, privkey.PADDINGS.RSA_PKCS1_OAEP_PADDING,{ + "rsa_oaep_md:sha256", + "rsa_mgf1_md:sha256", + })) + ngx.say(decrypted) + + local ok, err = privkey:decrypt(s, privkey.PADDINGS.RSA_PKCS1_OAEP_PADDING,{ + "rsa_oaep_md:sha256", + "rsa_mgf1_md:sha384", + }) + ngx.say(err) + } + } +--- request + GET /t +--- response_body_like eval +"256 +23333 +.+oaep decoding error.* +" +--- no_error_log +[error] + + + +=== TEST 24: signature: Sign and verify +--- http_config eval: $::HttpConfig +--- config + location =/t { + content_by_lua_block { + local p = myassert(require("resty.openssl.pkey").new()) + + local digest = myassert(require("resty.openssl.digest").new("SHA256")) + + myassert(digest:update("🕶️", "+1s")) + + local s = myassert(p:sign(digest)) + ngx.say(#s) + + local v = myassert(p:verify(s, digest)) + ngx.say(v) + } + } +--- request + GET /t +--- response_body eval +"256 +true +" +--- no_error_log +[error] + + + +=== TEST 25: signature: One shot sign and verify +--- http_config eval: $::HttpConfig +--- config + location =/t { + content_by_lua_block { + -- pureeddsa + local p = myassert(require("resty.openssl.pkey").new({ + type = "Ed25519" + })) + local digest = "23333" + local s = myassert(p:sign(digest)) + ngx.say(#s) + + local v = myassert(p:verify(s, digest)) + ngx.say(v) + + -- uses default md type + local p = myassert(require("resty.openssl.pkey").new({ + type = "RSA" + })) + local digest = "23333" + local s = myassert(p:sign(digest)) + ngx.say(#s) + + local v = myassert(p:verify(s, digest)) + ngx.say(v) + } + } +--- request + GET /t +--- response_body eval +"64 +true +256 +true +" +--- no_error_log +[error] + + + +=== TEST 26: signature: Error on bad digest or verify parameters +--- http_config eval: $::HttpConfig +--- config + location =/t { + content_by_lua_block { + local p = myassert(require("resty.openssl.pkey").new({ + type = "EC", + curve = "prime256v1", + })) + local s, err = p:sign(false) + ngx.say(err) + local v, err = p:verify("", false) + ngx.say(err) + local v, err = p:verify(false, "1") + ngx.say(err) + } + } +--- request + GET /t +--- response_body eval +"pkey:sign: expect a digest instance or a string at #1 +pkey:verify: expect a digest instance or a string at #2 +pkey:verify: expect a string at #1 +" +--- no_error_log +[error] + + + +=== TEST 27: signature: Raw sign and recover +--- http_config eval: $::HttpConfig +--- config + location =/t { + content_by_lua_block { + local p = myassert(require("resty.openssl.pkey").new()) + + local s = myassert(p:sign_raw("🕶️")) + ngx.say(#s) + + local v = myassert(p:verify_recover(s)) + ngx.say(v == "🕶️") + } + } +--- request + GET /t +--- response_body eval +"256 +true +" +--- no_error_log +[error] + + + +=== TEST 28: signature: Streaming sign and one shot sign can cross verify +--- http_config eval: $::HttpConfig +--- config + location =/t { + content_by_lua_block { + local p = myassert(require("resty.openssl.pkey").new()) + local pec = myassert(require("resty.openssl.pkey").new({ + type = "EC", + curve = "prime256v1", + })) + + -- one shot sign RSA, verify with digest instance + local s = myassert(p:sign("🕶️+1s")) + + local digest = myassert(require("resty.openssl.digest").new("SHA256")) + digest:update("🕶️+1s") + local v, err = p:verify(s, digest) + ngx.say(v) + + -- sign with digest RSA, one shot verify + local digest = myassert(require("resty.openssl.digest").new("SHA256")) + digest:update("🕶️+1s") + local s = myassert(p:sign(digest)) + + local v, err = p:verify(s, "🕶️+1s") + ngx.say(v) + + -- one shot sign EC, verify with digest instance + local s = myassert(pec:sign("🕶️+1s")) + + local digest = myassert(require("resty.openssl.digest").new("SHA256")) + digest:update("🕶️+1s") + local v, err = pec:verify(s, digest) + ngx.say(v) + + -- sign with digest EC, one shot verify + local digest = myassert(require("resty.openssl.digest").new("SHA256")) + digest:update("🕶️+1s") + local s = myassert(pec:sign(digest)) + + local v, err = pec:verify(s, "🕶️+1s") + ngx.say(v) + } + } +--- request + GET /t +--- response_body eval +"true +true +true +true +" +--- no_error_log +[error] + + + +=== TEST 29: signature: Sign/verify with md_alg +--- http_config eval: $::HttpConfig +--- config + location =/t { + content_by_lua_block { + -- uses default md type + local p = myassert(require("resty.openssl.pkey").new({ + type = "RSA" + })) + local digest = "23333" + local s = myassert(p:sign(digest, "sha512")) + ngx.say(#s) + + local ok = myassert(p:verify(s, digest, "sha512")) + ngx.say(ok) + + -- use wrong md type, should not pass + local ok, e = p:verify(s, digest, "sha256") + ngx.say(ok) + local ok, e = p:verify(s, digest, "md5") + ngx.say(ok) + } + } +--- request + GET /t +--- response_body eval +"256 +true +false +false +" +--- no_error_log +[error] + + + +=== TEST 30: signature: Sign/verify with paddings +--- http_config eval: $::HttpConfig +--- config + location =/t { + content_by_lua_block { + -- uses default md type + + local p = myassert(require("resty.openssl.pkey").new({ + type = "RSA" + })) + local digest = "23333" + local s = myassert(p:sign(digest, md, p.PADDINGS.RSA_PKCS1_PSS_PADDING)) + ngx.say(#s) + + local ok = myassert(p:verify(s, digest, md, p.PADDINGS.RSA_PKCS1_PSS_PADDING)) + ngx.say(ok) + + -- use wrong padding scheme, should not pass + local ok, e = p:verify(s, digest, nil) + if ok ~= false then ngx.say(e) else ngx.say(ok) end + local ok, e = p:verify(s, digest, nil, p.PADDINGS.RSA_PKCS1_PADDING) + if ok ~= false then ngx.say(e) else ngx.say(ok) end + } + } +--- request + GET /t +--- response_body eval +"256 +true +false +false +" +--- no_error_log +[error] + + + +=== TEST 31: signature: Sign/verify with PSS custom salt_len +--- http_config eval: $::HttpConfig +--- config + location =/t { + content_by_lua_block { + local p = myassert(require("resty.openssl.pkey").new({ + type = "RSA" + })) + local digest = "23333" + local s = myassert(p:sign(digest, nil, p.PADDINGS.RSA_PKCS1_PSS_PADDING, { + pss_saltlen = 64, + })) + ngx.say(#s) + + local ok = myassert(p:verify(s, digest, nil, p.PADDINGS.RSA_PKCS1_PSS_PADDING, { + pss_saltlen = 64, + })) + ngx.say(ok) + } + } +--- request + GET /t +--- response_body eval +"256 +true +" +--- no_error_log +[error] + + + +=== TEST 32: signature: Sign/verify with binary ecdsa sig --- http_config eval: $::HttpConfig --- config location =/t { @@ -1221,7 +1111,9 @@ nilpkey:sign: ecdsa.sig_raw2der: invalid signature length, expect 64 but got \\d --- no_error_log [error] -=== TEST 40: Sign/verify with binary ecdsa sig length + + +=== TEST 33: signature: Sign/verify with binary ecdsa sig length --- http_config eval: $::HttpConfig --- config location =/t { @@ -1260,3 +1152,257 @@ true true --- no_error_log [error] + + + +=== TEST 34: signature: Sign and verify with ctrl str +--- http_config eval: $::HttpConfig +--- config + location =/t { + content_by_lua_block { + local p = myassert(require("resty.openssl.pkey").new({ + type = "RSA" + })) + local digest = "23333" + local s = myassert(p:sign(digest, nil, p.PADDINGS.RSA_PKCS1_PSS_PADDING, { + pss_saltlen = 64, + })) + ngx.say(#s) + + local ok = myassert(p:verify(s, digest, nil, p.PADDINGS.RSA_PKCS1_PSS_PADDING, { + "rsa_pss_saltlen:64", + })) + ngx.say(ok) + } + } +--- request + GET /t +--- response_body eval +"256 +true +" +--- no_error_log +[error] + + + +=== TEST 35: signature: Get default digest type +--- http_config eval: $::HttpConfig +--- config + location =/t { + content_by_lua_block { + local pkey = require("resty.openssl.pkey") + local p = myassert(pkey.new({ type = "EC" })) + local algo = myassert(p:get_default_digest_type()) + ngx.say(require("cjson").encode(algo)) + } + } +--- request + GET /t +--- response_body_like +.+sha256.+ +--- no_error_log +[error] + + + +=== TEST 36: derivation: Key derivation for EC, X448 and X25519 +--- http_config eval: $::HttpConfig +--- config + location =/t { + content_by_lua_block { + for i, t in ipairs({"EC", "X25519", "X448"}) do + local p = myassert(require("resty.openssl.pkey").new({ + type = t, + curve = t == "EC" and "prime256v1" or nil, + })) + + -- usually the peer key is the pubkey from other key pair + -- we use the same key here just for simplicity + local k = myassert(p:derive(p)) + ngx.say(#k) + ::next:: + end + } + } +--- request + GET /t +--- response_body_like eval +"32 +32 +56" +--- no_error_log +[error] + + + +=== TEST 37: misc: get key type +--- http_config eval: $::HttpConfig +--- config + location =/t { + content_by_lua_block { + local p, err = myassert(require("resty.openssl.pkey").new({ + type = 'RSA', + })) + ngx.say(encode_sorted_json(p:get_key_type())) + } + } +--- request + GET /t +--- response_body_like eval +'{"id":"1.2.840.113549.1.1.1","ln":"rsaEncryption","nid":6,"sn":"rsaEncryption"}' +--- no_error_log +[error] + + + +=== TEST 38: misc: Checks if it's private key +--- http_config eval: $::HttpConfig +--- config + location =/t { + content_by_lua_block { + local opts = { + { type = 'RSA', bits = 1024 }, + { type = "EC", curve = "prime256v1" }, + { type = 'DH', group = "dh_1024_160",}, + } + for _, opt in ipairs(opts) do + local priv = myassert(require("resty.openssl.pkey").new(opt)) + + local ok, err = priv:is_private() + if not ok then + ngx.say(opt.type .. ": should be a private key, but returns false: ".. (err or "nil")) + end + + local pem = myassert(priv:to_PEM("public")) + + local pub = myassert(require("resty.openssl.pkey").new(pem)) + + local ok, err = pub:is_private() + if ok then + ngx.say(opt.type .. ": should not be a private key, but returns true: ".. (err or "nil")) + end + end + } + } +--- request + GET /t +--- response_body eval +"" +--- no_error_log +[error] + + + +=== TEST 39: misc: Checks if it's private key: ecx +--- http_config eval: $::HttpConfig +--- config + location =/t { + content_by_lua_block { + local opts = { + { type = 'Ed25519'}, + } + for _, opt in ipairs(opts) do + local priv = myassert(require("resty.openssl.pkey").new(opt)) + + local ok, err = priv:is_private() + if not ok then + ngx.say(opt.type .. ": should be a private key, but returns false: ".. (err or "nil")) + end + + local pem = myassert(priv:to_PEM("public")) + + local pub = myassert(require("resty.openssl.pkey").new(pem)) + + local ok, err = pub:is_private() + if ok then + ngx.say(opt.type .. ": should not be a private key, but returns true: ".. (err or "nil")) + end + end + } + } +--- request + GET /t +--- response_body eval +"" +--- no_error_log +[error] + + + +=== TEST 40: misc: Returns provider +--- http_config eval: $::HttpConfig +--- config + location =/t { + content_by_lua_block { + if not require("resty.openssl.version").OPENSSL_3X then + ngx.say("default") + ngx.exit(0) + end + + local pkey = require("resty.openssl.pkey") + local p = myassert(pkey.new({ type = "EC" })) + ngx.say(myassert(p:get_provider_name())) + } + } +--- request + GET /t +--- response_body +default +--- no_error_log +[error] + + + +=== TEST 41: params: Returns gettable, settable params +--- http_config eval: $::HttpConfig +--- config + location =/t { + content_by_lua_block { + if not require("resty.openssl.version").OPENSSL_3X then + ngx.say("-bits-\n-encoding-") + ngx.exit(0) + end + + local pkey = require("resty.openssl.pkey") + local p = myassert(pkey.new({ type = "EC" })) + ngx.say(require("cjson").encode(myassert(p:gettable_params()))) + ngx.say(require("cjson").encode(myassert(p:settable_params()))) + } + } +--- request + GET /t +--- response_body_like +.+bits.+ +.+encoding.+ +--- no_error_log +[error] + + + +=== TEST 42: params: Get params, set params +--- http_config eval: $::HttpConfig +--- config + location =/t { + content_by_lua_block { + if not require("resty.openssl.version").OPENSSL_3X then + ngx.say("true") + ngx.exit(0) + end + + local pkey = require("resty.openssl.pkey") + local p = myassert(pkey.new({ type = "EC" })) + local priv = myassert(p:get_param("priv", nil, "bn")) + local priv2 = p:get_parameters().private + ngx.say(priv == priv2) + + myassert(p:set_params({["point-format"] = "UNCOMPRESSED"})) + } + } +--- request + GET /t +--- response_body eval +"true +" +--- no_error_log +[error] diff --git a/t/openssl/provider.t b/t/openssl/provider.t index 8a86d96c2..b226afec1 100644 --- a/t/openssl/provider.t +++ b/t/openssl/provider.t @@ -23,6 +23,7 @@ our $HttpConfig = qq{ run_tests(); __DATA__ + === TEST 1: Loads default and legacy provider --- http_config eval: $::HttpConfig --- config @@ -59,6 +60,8 @@ true --- no_error_log [error] + + === TEST 2: Self test default and legacy provider --- http_config eval: $::HttpConfig --- config @@ -91,13 +94,15 @@ true --- no_error_log [error] + + === TEST 3: Set default search path --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { if not require("resty.openssl.version").OPENSSL_3X then - ngx.say("true\ncommon libcrypto routines::init fail") + ngx.say("true\ncommon libcrypto routines:provider_init:") ngx.exit(0) end @@ -112,10 +117,12 @@ true GET /t --- response_body_like true -.+(?:init fail|common libcrypto routines::reason\(\d+\)) +.*(?:init fail|common libcrypto routines:provider_init).* --- no_error_log [error] + + === TEST 4: Get parameters --- http_config eval: $::HttpConfig --- config @@ -138,4 +145,3 @@ true {"buildinfo":"3.+","name":"OpenSSL Default Provider","status":1,"version":"3.+"} --- no_error_log [error] - diff --git a/t/openssl/rand.t b/t/openssl/rand.t index af1e58c3b..371d17f03 100644 --- a/t/openssl/rand.t +++ b/t/openssl/rand.t @@ -21,6 +21,7 @@ our $HttpConfig = qq{ run_tests(); __DATA__ + === TEST 1: Geneartes random bytes --- http_config eval: $::HttpConfig --- config @@ -53,6 +54,7 @@ false [error] + === TEST 2: Rejects invalid arguments --- http_config eval: $::HttpConfig --- config @@ -76,5 +78,3 @@ rand.bytes: expect a number at #1 " --- no_error_log [error] - - diff --git a/t/openssl/version.t b/t/openssl/version.t index 30df4a2e8..4998b6c81 100644 --- a/t/openssl/version.t +++ b/t/openssl/version.t @@ -21,6 +21,7 @@ our $HttpConfig = qq{ run_tests(); __DATA__ + === TEST 1: Prints version text properly --- http_config eval: $::HttpConfig --- config @@ -33,10 +34,12 @@ __DATA__ --- request GET /t --- response_body_like -(OpenSSL \d.\d.\d.+|BoringSSL) +OpenSSL \d.\d.\d.+ --- no_error_log [error] + + === TEST 2: Prints version text using version() --- http_config eval: $::HttpConfig --- config @@ -50,7 +53,7 @@ __DATA__ --- request GET /t --- response_body_like -(OpenSSL \d.\d.\d.+|BoringSSL) +OpenSSL \d.\d.\d.+ compiler:.+ --- no_error_log [error] diff --git a/t/openssl/x509.t b/t/openssl/x509.t index 3ef58771f..5ed42af14 100644 --- a/t/openssl/x509.t +++ b/t/openssl/x509.t @@ -25,6 +25,7 @@ no_long_string(); run_tests(); __DATA__ + === TEST 1: Loads a cert --- http_config eval: $::HttpConfig --- config @@ -43,6 +44,8 @@ __DATA__ --- no_error_log [error] + + === TEST 2: Converts and loads PEM format --- http_config eval: $::HttpConfig --- config @@ -63,10 +66,12 @@ __DATA__ --- request GET /t --- response_body_like eval -"x509.new.+(nested asn1 error|NESTED_ASN1_ERROR).+" +"x509.new.+nested asn1 error.+" --- no_error_log [error] + + === TEST 3: Converts and loads DER format --- http_config eval: $::HttpConfig --- config @@ -87,10 +92,12 @@ __DATA__ --- request GET /t --- response_body_like eval -"x509.new.+(no start line|NO_START_LINE).+" +"x509.new.+no start line.+" --- no_error_log [error] + + === TEST 4: Rejectes invalid cert --- http_config eval: $::HttpConfig --- config @@ -107,11 +114,13 @@ __DATA__ GET /t --- response_body_like eval "expect nil or a string at #1 -x509.new: .*(not enough data|NOT_ENOUGH_DATA) +x509.new: .*not enough data.* " --- no_error_log [error] + + === TEST 5: Calculates cert digest --- http_config eval: $::HttpConfig --- config @@ -121,7 +130,7 @@ x509.new: .*(not enough data|NOT_ENOUGH_DATA) local c = myassert(require("resty.openssl.x509").new(f)) local dd = myassert(c:digest()) - local h = string.upper(myassert(require("helper").to_hex(dd))) + local h = myassert(require("helper").to_hex(dd)) ngx.say(h) } } @@ -133,6 +142,8 @@ x509.new: .*(not enough data|NOT_ENOUGH_DATA) --- no_error_log [error] + + === TEST 6: Calculates pubkey digest --- http_config eval: $::HttpConfig --- config @@ -142,7 +153,7 @@ x509.new: .*(not enough data|NOT_ENOUGH_DATA) local c = myassert(require("resty.openssl.x509").new(f)) local dd = myassert(c:pubkey_digest()) - local h, err = string.upper(require("helper").to_hex(dd)) + local h, err = require("helper").to_hex(dd) ngx.say(h) } } @@ -154,6 +165,8 @@ x509.new: .*(not enough data|NOT_ENOUGH_DATA) --- no_error_log [error] + + === TEST 7: Gets extension --- http_config eval: $::HttpConfig --- config @@ -176,6 +189,8 @@ TLS Web Server Authentication, TLS Web Client Authentication --- no_error_log [error] + + === TEST 8: Adds extension --- http_config eval: $::HttpConfig --- config @@ -201,6 +216,8 @@ TLS Web Server Authentication, TLS Web Client Authentication --- no_error_log [error] + + === TEST 9: Set extension --- http_config eval: $::HttpConfig --- config @@ -227,6 +244,7 @@ TLS Web Server Authentication, TLS Web Client Authentication [error] + === TEST 10: Reads basic constraints --- http_config eval: $::HttpConfig --- config @@ -248,6 +266,8 @@ TLS Web Server Authentication, TLS Web Client Authentication --- no_error_log [error] + + === TEST 11: Set basic constraints --- http_config eval: $::HttpConfig --- config @@ -274,6 +294,8 @@ TLS Web Server Authentication, TLS Web Client Authentication --- no_error_log [error] + + === TEST 12: Get authority info access --- http_config eval: $::HttpConfig --- config @@ -299,6 +321,8 @@ CA Issuers - URI:http://cacerts.digicert.com/DigiCertHighAssuranceTLSHybridECCSH --- no_error_log [error] + + === TEST 13: Set authority info access --- http_config eval: $::HttpConfig --- config @@ -329,6 +353,8 @@ OCSP - URI:http://somedomain.com --- no_error_log [error] + + === TEST 14: Get CRL distribution points --- http_config eval: $::HttpConfig --- config @@ -356,6 +382,8 @@ URI http://crl4.digicert.com/DigiCertHighAssuranceTLSHybridECCSHA2562020CA1.crl --- no_error_log [error] + + === TEST 15: Set CRL distribution points --- http_config eval: $::HttpConfig --- config @@ -369,6 +397,8 @@ URI http://crl4.digicert.com/DigiCertHighAssuranceTLSHybridECCSHA2562020CA1.crl --- no_error_log [error] + + === TEST 16: Get OCSP url --- http_config eval: $::HttpConfig --- config @@ -399,6 +429,8 @@ nil --- no_error_log [error] + + === TEST 17: Get CRL url --- http_config eval: $::HttpConfig --- config @@ -429,6 +461,8 @@ nil --- no_error_log [error] + + === TEST 18: Get non existend extension, return nil, nil --- http_config eval: $::HttpConfig --- config @@ -449,12 +483,14 @@ nil --- no_error_log [error] + + === TEST 19: Check private key match --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { - local cert, key = require("helper").create_self_signed({ type = "EC", curve = "prime256v1" }) + local cert, key = require("helper").create_self_signed({ type = "EC" }) local ok, err = cert:check_private_key(key) ngx.say(ok) ngx.say(err) @@ -467,7 +503,6 @@ nil local key2 = require("resty.openssl.pkey").new({ type = 'EC', - curve = "prime256v1", }) local ok, err = cert:check_private_key(key2) ngx.say(ok) @@ -480,8 +515,8 @@ nil "true nil false -.+(key type mismatch|KEY_TYPE_MISMATCH) -.+(key values mismatch|KEY_VALUES_MISMATCH) +.+key type mismatch.* +.+key values mismatch.* " --- no_error_log [error] @@ -489,6 +524,7 @@ false # START AUTO GENERATED CODE + === TEST 20: x509:get_serial_number (AUTOGEN) --- http_config eval: $::HttpConfig --- config @@ -498,7 +534,7 @@ false local c = myassert(require("resty.openssl.x509").new(f)) local get = myassert(c:get_serial_number()) - get = get:to_hex():upper() + get = get:to_hex() ngx.print(get) } } @@ -509,6 +545,8 @@ false --- no_error_log [error] + + === TEST 21: x509:set_serial_number (AUTOGEN) --- http_config eval: $::HttpConfig --- config @@ -520,8 +558,8 @@ false local ok = myassert(c:set_serial_number(toset)) local get = myassert(c:get_serial_number()) - get = get:to_hex():upper() - toset = toset:to_hex():upper() + get = get:to_hex() + toset = toset:to_hex() if get ~= toset then ngx.say(get) ngx.say(toset) @@ -537,6 +575,8 @@ false --- no_error_log [error] + + === TEST 22: x509:get_not_before (AUTOGEN) --- http_config eval: $::HttpConfig --- config @@ -556,6 +596,8 @@ false --- no_error_log [error] + + === TEST 23: x509:set_not_before (AUTOGEN) --- http_config eval: $::HttpConfig --- config @@ -582,6 +624,8 @@ false --- no_error_log [error] + + === TEST 24: x509:get_not_after (AUTOGEN) --- http_config eval: $::HttpConfig --- config @@ -601,6 +645,8 @@ false --- no_error_log [error] + + === TEST 25: x509:set_not_after (AUTOGEN) --- http_config eval: $::HttpConfig --- config @@ -627,6 +673,8 @@ false --- no_error_log [error] + + === TEST 26: x509:get_pubkey (AUTOGEN) --- http_config eval: $::HttpConfig --- config @@ -651,6 +699,8 @@ Tp+h/rnQjL05vAwjx8+RppBa2EWrAxO+wSN6ucTInUf2luC5dmtQNmb3DQ== --- no_error_log [error] + + === TEST 27: x509:set_pubkey (AUTOGEN) --- http_config eval: $::HttpConfig --- config @@ -679,6 +729,8 @@ Tp+h/rnQjL05vAwjx8+RppBa2EWrAxO+wSN6ucTInUf2luC5dmtQNmb3DQ== --- no_error_log [error] + + === TEST 28: x509:get_subject_name (AUTOGEN) --- http_config eval: $::HttpConfig --- config @@ -699,6 +751,8 @@ Tp+h/rnQjL05vAwjx8+RppBa2EWrAxO+wSN6ucTInUf2luC5dmtQNmb3DQ== --- no_error_log [error] + + === TEST 29: x509:set_subject_name (AUTOGEN) --- http_config eval: $::HttpConfig --- config @@ -727,6 +781,8 @@ Tp+h/rnQjL05vAwjx8+RppBa2EWrAxO+wSN6ucTInUf2luC5dmtQNmb3DQ== --- no_error_log [error] + + === TEST 30: x509:get_issuer_name (AUTOGEN) --- http_config eval: $::HttpConfig --- config @@ -747,6 +803,8 @@ Tp+h/rnQjL05vAwjx8+RppBa2EWrAxO+wSN6ucTInUf2luC5dmtQNmb3DQ== --- no_error_log [error] + + === TEST 31: x509:set_issuer_name (AUTOGEN) --- http_config eval: $::HttpConfig --- config @@ -775,6 +833,8 @@ Tp+h/rnQjL05vAwjx8+RppBa2EWrAxO+wSN6ucTInUf2luC5dmtQNmb3DQ== --- no_error_log [error] + + === TEST 32: x509:get_version (AUTOGEN) --- http_config eval: $::HttpConfig --- config @@ -794,6 +854,8 @@ Tp+h/rnQjL05vAwjx8+RppBa2EWrAxO+wSN6ucTInUf2luC5dmtQNmb3DQ== --- no_error_log [error] + + === TEST 33: x509:set_version (AUTOGEN) --- http_config eval: $::HttpConfig --- config @@ -820,6 +882,8 @@ Tp+h/rnQjL05vAwjx8+RppBa2EWrAxO+wSN6ucTInUf2luC5dmtQNmb3DQ== --- no_error_log [error] + + === TEST 34: x509:get_subject_alt_name (AUTOGEN) --- http_config eval: $::HttpConfig --- config @@ -840,6 +904,8 @@ Tp+h/rnQjL05vAwjx8+RppBa2EWrAxO+wSN6ucTInUf2luC5dmtQNmb3DQ== --- no_error_log [error] + + === TEST 35: x509:set_subject_alt_name (AUTOGEN) --- http_config eval: $::HttpConfig --- config @@ -868,7 +934,9 @@ Tp+h/rnQjL05vAwjx8+RppBa2EWrAxO+wSN6ucTInUf2luC5dmtQNmb3DQ== --- no_error_log [error] -=== TEST 37: x509:get/set_subject_alt_name_critical (AUTOGEN) + + +=== TEST 36: x509:get/set_subject_alt_name_critical (AUTOGEN) --- http_config eval: $::HttpConfig --- config location =/t { @@ -890,7 +958,9 @@ true --- no_error_log [error] -=== TEST 38: x509:get/set_basic_constraints_critical (AUTOGEN) + + +=== TEST 37: x509:get/set_basic_constraints_critical (AUTOGEN) --- http_config eval: $::HttpConfig --- config location =/t { @@ -912,7 +982,9 @@ true --- no_error_log [error] -=== TEST 39: x509:get/set_info_access_critical (AUTOGEN) + + +=== TEST 38: x509:get/set_info_access_critical (AUTOGEN) --- http_config eval: $::HttpConfig --- config location =/t { @@ -934,7 +1006,9 @@ true --- no_error_log [error] -=== TEST 40: x509:get/set_crl_distribution_points_critical (AUTOGEN) + + +=== TEST 39: x509:get/set_crl_distribution_points_critical (AUTOGEN) --- http_config eval: $::HttpConfig --- config location =/t { @@ -956,7 +1030,9 @@ true --- no_error_log [error] -=== TEST 41: x509:get_get_signature_name (AUTOGEN) + + +=== TEST 40: x509:get_signature_name (AUTOGEN) --- http_config eval: $::HttpConfig --- config location =/t { @@ -985,4 +1061,4 @@ ecdsa-with-SHA256 SHA256 --- no_error_log [error] -# END AUTO GENERATED CODE \ No newline at end of file +# END AUTO GENERATED CODE diff --git a/t/openssl/x509/altname.t b/t/openssl/x509/altname.t index a6692d7f2..23d1a445d 100644 --- a/t/openssl/x509/altname.t +++ b/t/openssl/x509/altname.t @@ -23,6 +23,7 @@ our $HttpConfig = qq{ run_tests(); __DATA__ + === TEST 1: Creates stack properly --- http_config eval: $::HttpConfig --- config @@ -41,6 +42,8 @@ __DATA__ --- no_error_log [error] + + === TEST 2: Adds elements to stack properly --- http_config eval: $::HttpConfig --- config @@ -65,6 +68,8 @@ __DATA__ --- no_error_log [error] + + === TEST 3: Element can be indexed properly --- http_config eval: $::HttpConfig --- config @@ -91,6 +96,8 @@ DNS 2.com --- no_error_log [error] + + === TEST 4: Element is duplicated when added to stack --- http_config eval: $::HttpConfig --- config @@ -115,6 +122,8 @@ DNS 2.com --- no_error_log [error] + + === TEST 5: Element is duplicated when returned --- http_config eval: $::HttpConfig --- config @@ -144,6 +153,8 @@ DNS 2.com --- no_error_log [error] + + === TEST 6: Element is not freed when stack is duplicated --- http_config eval: $::HttpConfig --- config @@ -172,6 +183,8 @@ DNS example.com --- no_error_log [error] + + === TEST 7: Unsupported SANs are returned as "unsupported" --- http_config eval: $::HttpConfig --- config @@ -206,6 +219,8 @@ RID:RID: --- no_error_log [error] + + === TEST 8: IP addresses are validated and parsed --- http_config eval: $::HttpConfig --- config @@ -235,4 +250,4 @@ RID:RID: --- response_body IP=1.2.3.4/IP=100.100.100.100/IP=255.255.255.255/IP=::1/IP=ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff --- no_error_log -[error] \ No newline at end of file +[error] diff --git a/t/openssl/x509/chain.t b/t/openssl/x509/chain.t index a4e5d3df2..2bdce409c 100644 --- a/t/openssl/x509/chain.t +++ b/t/openssl/x509/chain.t @@ -23,6 +23,7 @@ our $HttpConfig = qq{ run_tests(); __DATA__ + === TEST 1: Creates stack properly --- http_config eval: $::HttpConfig --- config @@ -42,6 +43,8 @@ __DATA__ --- no_error_log [error] + + === TEST 2: Adds elements to stack properly --- http_config eval: $::HttpConfig --- config @@ -67,6 +70,8 @@ __DATA__ --- no_error_log [error] + + === TEST 3: Element can be indexed properly --- http_config eval: $::HttpConfig --- config @@ -95,6 +100,8 @@ __DATA__ --- no_error_log [error] + + === TEST 4: Element is duplicated when added to stack --- http_config eval: $::HttpConfig --- config @@ -119,6 +126,8 @@ __DATA__ --- no_error_log [error] + + === TEST 5: Element is duplicated when returned --- http_config eval: $::HttpConfig --- config @@ -144,6 +153,8 @@ __DATA__ --- no_error_log [error] + + === TEST 6: Element is not freed when stack is duplicated --- http_config eval: $::HttpConfig --- config @@ -170,4 +181,4 @@ __DATA__ 20 " --- no_error_log -[error] \ No newline at end of file +[error] diff --git a/t/openssl/x509/crl.t b/t/openssl/x509/crl.t index c5c774427..b24930da0 100644 --- a/t/openssl/x509/crl.t +++ b/t/openssl/x509/crl.t @@ -24,6 +24,7 @@ no_long_string(); run_tests(); __DATA__ + === TEST 1: Loads a crl --- http_config eval: $::HttpConfig --- config @@ -43,6 +44,8 @@ __DATA__ --- no_error_log [error] + + === TEST 2: Converts and loads PEM format --- http_config eval: $::HttpConfig --- config @@ -63,10 +66,12 @@ __DATA__ --- request GET /t --- response_body_like eval -"x509.crl.new.+(nested asn1 error|NESTED_ASN1_ERROR).+" +"x509.crl.new.+nested asn1 error.+" --- no_error_log [error] + + === TEST 3: Converts and loads DER format --- http_config eval: $::HttpConfig --- config @@ -87,10 +92,12 @@ __DATA__ --- request GET /t --- response_body_like eval -"x509.crl.new.+(no start line|NO_START_LINE).+" +"x509.crl.new.+no start line.+" --- no_error_log [error] + + === TEST 4: x509.crl:add_revoked should add revoked to crl --- http_config eval: $::HttpConfig --- config @@ -122,6 +129,8 @@ __DATA__ --- no_error_log [error] + + === TEST 5: x509.crl:add_revoked should fail if revoked is not instance of revoked --- http_config eval: $::HttpConfig --- config @@ -149,6 +158,7 @@ __DATA__ [error] + === TEST 6: x509.crl:sign should succeed --- http_config eval: $::HttpConfig --- config @@ -178,6 +188,8 @@ __DATA__ --- no_error_log [error] + + === TEST 7: x509.crl:text --- http_config eval: $::HttpConfig --- config @@ -195,6 +207,8 @@ __DATA__ --- no_error_log [error] + + === TEST 8: x509.crl metamethods --- http_config eval: $::HttpConfig --- config @@ -229,6 +243,8 @@ __DATA__ --- no_error_log [error] + + === TEST 9: x509.crl get_by_serial --- http_config eval: $::HttpConfig --- config @@ -255,6 +271,8 @@ truetrue --- no_error_log [error] + + === TEST 10: x509.crl doesn't error if revoked is empty (regression) --- http_config eval: $::HttpConfig --- config @@ -282,6 +300,7 @@ truetrue # START AUTO GENERATED CODE + === TEST 11: x509.crl:get_issuer_name (AUTOGEN) --- http_config eval: $::HttpConfig --- config @@ -302,6 +321,8 @@ truetrue --- no_error_log [error] + + === TEST 12: x509.crl:set_issuer_name (AUTOGEN) --- http_config eval: $::HttpConfig --- config @@ -330,6 +351,8 @@ truetrue --- no_error_log [error] + + === TEST 13: x509.crl:get_last_update (AUTOGEN) --- http_config eval: $::HttpConfig --- config @@ -349,6 +372,8 @@ truetrue --- no_error_log [error] + + === TEST 14: x509.crl:set_last_update (AUTOGEN) --- http_config eval: $::HttpConfig --- config @@ -375,6 +400,8 @@ truetrue --- no_error_log [error] + + === TEST 15: x509.crl:get_next_update (AUTOGEN) --- http_config eval: $::HttpConfig --- config @@ -394,6 +421,8 @@ truetrue --- no_error_log [error] + + === TEST 16: x509.crl:set_next_update (AUTOGEN) --- http_config eval: $::HttpConfig --- config @@ -420,6 +449,8 @@ truetrue --- no_error_log [error] + + === TEST 17: x509.crl:get_version (AUTOGEN) --- http_config eval: $::HttpConfig --- config @@ -439,6 +470,8 @@ truetrue --- no_error_log [error] + + === TEST 18: x509.crl:set_version (AUTOGEN) --- http_config eval: $::HttpConfig --- config @@ -465,7 +498,9 @@ truetrue --- no_error_log [error] -=== TEST 20: x509.crl:get_get_signature_name (AUTOGEN) + + +=== TEST 19: x509.crl:get_signature_name (AUTOGEN) --- http_config eval: $::HttpConfig --- config location =/t { diff --git a/t/openssl/x509/csr.t b/t/openssl/x509/csr.t index 42d8239e6..19dccc771 100644 --- a/t/openssl/x509/csr.t +++ b/t/openssl/x509/csr.t @@ -24,6 +24,7 @@ no_long_string(); run_tests(); __DATA__ + === TEST 1: Loads a csr --- http_config eval: $::HttpConfig --- config @@ -43,6 +44,8 @@ __DATA__ --- no_error_log [error] + + === TEST 2: Converts and loads PEM format --- http_config eval: $::HttpConfig --- config @@ -63,10 +66,12 @@ __DATA__ --- request GET /t --- response_body_like eval -"x509.csr.new.+(nested asn1 error|NESTED_ASN1_ERROR).+" +"x509.csr.new.+nested asn1 error.+" --- no_error_log [error] + + === TEST 3: Converts and loads DER format --- http_config eval: $::HttpConfig --- config @@ -87,10 +92,12 @@ __DATA__ --- request GET /t --- response_body_like eval -"x509.csr.new.+(no start line|NO_START_LINE).+" +"x509.csr.new.+no start line.+" --- no_error_log [error] + + === TEST 4: Generates CSR with RSA pkey correctly --- http_config eval: $::HttpConfig --- config @@ -116,6 +123,8 @@ __DATA__ --- no_error_log [error] + + === TEST 5: Rejects invalid arguments --- http_config eval: $::HttpConfig --- config @@ -144,6 +153,7 @@ x509.csr:sign: expect a pkey instance at #1 [error] + === TEST 6: x509.csr:get_extensions of csr --- http_config eval: $::HttpConfig --- config @@ -167,6 +177,7 @@ x509.csr:sign: expect a pkey instance at #1 [error] + === TEST 7: x509.csr:get_extension by nid --- http_config eval: $::HttpConfig --- config @@ -198,6 +209,8 @@ nil --- no_error_log [error] + + === TEST 8: x509.csr:get_extension by nid name --- http_config eval: $::HttpConfig --- config @@ -220,6 +233,8 @@ nil --- no_error_log [error] + + === TEST 9: x509.csr:get_extension should return nil if wrong nid name is given --- http_config eval: $::HttpConfig --- config @@ -242,6 +257,8 @@ nil --- no_error_log [error] + + === TEST 10: Adds extension --- http_config eval: $::HttpConfig --- config @@ -276,6 +293,8 @@ nil --- no_error_log [error] + + === TEST 11: Set extension --- http_config eval: $::HttpConfig --- config @@ -304,6 +323,8 @@ nil --- no_error_log [error] + + === TEST 12: x509.csr:sign should succeed --- http_config eval: $::HttpConfig --- config @@ -328,13 +349,15 @@ nil --- no_error_log [error] -=== TEST 14: Check private key match + + +=== TEST 13: Check private key match --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { local util = require("csr") - local pkey = require("resty.openssl.pkey").new({ type = "EC", curve = "prime256v1" }) + local pkey = require("resty.openssl.pkey").new({ type = "EC" }) local der = myassert(util.create_csr(pkey, "dns1.com", "dns2.com", "dns3.com")) local csr = myassert(require("resty.openssl.x509.csr").new(der)) local ok, err = csr:check_private_key(pkey) @@ -349,7 +372,6 @@ nil local key2 = require("resty.openssl.pkey").new({ type = 'EC', - curve = "prime256v1", }) local ok, err = csr:check_private_key(key2) ngx.say(ok) @@ -362,8 +384,8 @@ nil "true nil false -.+(key type mismatch|KEY_TYPE_MISMATCH) -.+(key values mismatch|KEY_VALUES_MISMATCH) +.+key type mismatch.* +.+key values mismatch.* " --- no_error_log [error] @@ -371,7 +393,8 @@ false # START AUTO GENERATED CODE -=== TEST 15: x509.csr:get_subject_name (AUTOGEN) + +=== TEST 14: x509.csr:get_subject_name (AUTOGEN) --- http_config eval: $::HttpConfig --- config location =/t { @@ -391,7 +414,9 @@ false --- no_error_log [error] -=== TEST 16: x509.csr:set_subject_name (AUTOGEN) + + +=== TEST 15: x509.csr:set_subject_name (AUTOGEN) --- http_config eval: $::HttpConfig --- config location =/t { @@ -419,7 +444,9 @@ false --- no_error_log [error] -=== TEST 17: x509.csr:get_pubkey (AUTOGEN) + + +=== TEST 16: x509.csr:get_pubkey (AUTOGEN) --- http_config eval: $::HttpConfig --- config location =/t { @@ -448,7 +475,9 @@ cwIDAQAB --- no_error_log [error] -=== TEST 18: x509.csr:set_pubkey (AUTOGEN) + + +=== TEST 17: x509.csr:set_pubkey (AUTOGEN) --- http_config eval: $::HttpConfig --- config location =/t { @@ -476,7 +505,9 @@ cwIDAQAB --- no_error_log [error] -=== TEST 19: x509.csr:get_version (AUTOGEN) + + +=== TEST 18: x509.csr:get_version (AUTOGEN) --- http_config eval: $::HttpConfig --- config location =/t { @@ -495,7 +526,9 @@ cwIDAQAB --- no_error_log [error] -=== TEST 20: x509.csr:set_version (AUTOGEN) + + +=== TEST 19: x509.csr:set_version (AUTOGEN) --- http_config eval: $::HttpConfig --- config location =/t { @@ -521,7 +554,9 @@ cwIDAQAB --- no_error_log [error] -=== TEST 21: x509.csr:get_subject_alt_name (AUTOGEN) + + +=== TEST 20: x509.csr:get_subject_alt_name (AUTOGEN) --- http_config eval: $::HttpConfig --- config location =/t { @@ -541,7 +576,9 @@ cwIDAQAB --- no_error_log [error] -=== TEST 22: x509.csr:set_subject_alt_name (AUTOGEN) + + +=== TEST 21: x509.csr:set_subject_alt_name (AUTOGEN) --- http_config eval: $::HttpConfig --- config location =/t { @@ -569,7 +606,9 @@ cwIDAQAB --- no_error_log [error] -=== TEST 24: x509.csr:get/set_subject_alt_name_critical (AUTOGEN) + + +=== TEST 22: x509.csr:get/set_subject_alt_name_critical (AUTOGEN) --- http_config eval: $::HttpConfig --- config location =/t { @@ -591,7 +630,9 @@ true --- no_error_log [error] -=== TEST 25: x509.csr:get_get_signature_name (AUTOGEN) + + +=== TEST 23: x509.csr:get_signature_name (AUTOGEN) --- http_config eval: $::HttpConfig --- config location =/t { diff --git a/t/openssl/x509/extension.t b/t/openssl/x509/extension.t index a4e8c43c1..decb512da 100644 --- a/t/openssl/x509/extension.t +++ b/t/openssl/x509/extension.t @@ -24,6 +24,7 @@ our $HttpConfig = qq{ run_tests(); __DATA__ + === TEST 1: Creates extension by nconf --- http_config eval: $::HttpConfig --- config @@ -39,6 +40,8 @@ __DATA__ --- no_error_log [error] + + === TEST 2: Gets extension object --- http_config eval: $::HttpConfig --- config @@ -59,6 +62,8 @@ __DATA__ --- no_error_log [error] + + === TEST 3: Gets extension critical --- http_config eval: $::HttpConfig --- config @@ -91,6 +96,8 @@ false --- no_error_log [error] + + === TEST 4: Set extension critical --- http_config eval: $::HttpConfig --- config @@ -115,6 +122,8 @@ true --- no_error_log [error] + + === TEST 5: Prints human readable txt of extension --- http_config eval: $::HttpConfig --- config @@ -163,6 +172,8 @@ CA Issuers - URI:http://cacerts.digicert.com/DigiCertHighAssuranceTLSHybridECCSH --- no_error_log [error] + + === TEST 6: Creates extension by X509V3_CTX --- http_config eval: $::HttpConfig --- config @@ -222,6 +233,8 @@ keyid:CF:03:F5:09:EB:83:D2:4F:10:DE:65:92:90:E9:93:3E:38:4C:E8:7C --- no_error_log [error] + + === TEST 7: Creates extension by data --- http_config eval: $::HttpConfig --- config @@ -246,6 +259,8 @@ DNS:test.com, DNS:test2.com --- no_error_log [error] + + === TEST 8: Convert extension to data --- http_config eval: $::HttpConfig --- config @@ -269,6 +284,8 @@ DNS:test.com, DNS:test2.com --- no_error_log [error] + + === TEST 9: Creates extension by der --- http_config eval: $::HttpConfig --- config @@ -288,6 +305,8 @@ DNS:test.com, DNS:test2.com --- no_error_log [error] + + === TEST 10: Creates extension by nconf --- http_config eval: $::HttpConfig --- config @@ -330,6 +349,8 @@ Policy: 1.3.5.8 --- no_error_log [error] + + === TEST 11: Returns DER encoded data --- http_config eval: $::HttpConfig --- config @@ -360,4 +381,4 @@ Policy: 1.3.5.8 308182302406082B060105050730018618687474703A2F2F6F6373702E64696769636572742E636F6D305A06082B06010505073002864E687474703A2F2F636163657274732E64696769636572742E636F6D2F4469676943657274486967684173737572616E6365544C53487962726964454343534841323536323032304341312E637274 " --- no_error_log -[error] \ No newline at end of file +[error] diff --git a/t/openssl/x509/extensions.t b/t/openssl/x509/extensions.t index 112e033e0..b1ab8b670 100644 --- a/t/openssl/x509/extensions.t +++ b/t/openssl/x509/extensions.t @@ -23,6 +23,7 @@ our $HttpConfig = qq{ run_tests(); __DATA__ + === TEST 1: Creates stack properly --- http_config eval: $::HttpConfig --- config @@ -42,6 +43,8 @@ __DATA__ --- no_error_log [error] + + === TEST 2: Adds elements to stack properly --- http_config eval: $::HttpConfig --- config @@ -68,6 +71,8 @@ __DATA__ --- no_error_log [error] + + === TEST 3: Element can be indexed properly --- http_config eval: $::HttpConfig --- config @@ -99,6 +104,8 @@ TLS Web Server Authentication, TLS Web Client Authentication --- no_error_log [error] + + === TEST 4: Element is duplicated when added to stack --- http_config eval: $::HttpConfig --- config @@ -124,6 +131,8 @@ TLS Web Server Authentication, TLS Web Client Authentication --- no_error_log [error] + + === TEST 5: Element is duplicated when returned --- http_config eval: $::HttpConfig --- config @@ -150,6 +159,8 @@ TLS Web Server Authentication, TLS Web Client Authentication --- no_error_log [error] + + === TEST 6: Element is not freed when stack is duplicated --- http_config eval: $::HttpConfig --- config diff --git a/t/openssl/x509/name.t b/t/openssl/x509/name.t index 7f1641298..2c2e9380e 100644 --- a/t/openssl/x509/name.t +++ b/t/openssl/x509/name.t @@ -23,6 +23,7 @@ our $HttpConfig = qq{ run_tests(); __DATA__ + === TEST 1: Duplicate the ctx --- http_config eval: $::HttpConfig --- config @@ -47,6 +48,8 @@ __DATA__ --- no_error_log [error] + + === TEST 2: Rejects invalid NID --- http_config eval: $::HttpConfig --- config @@ -68,6 +71,8 @@ x509.name:add: invalid NID text whatever --- no_error_log [error] + + === TEST 3: Finds by text --- http_config eval: $::HttpConfig --- config @@ -109,6 +114,7 @@ found 2 anotherdomain.com [error] + === TEST 4: Pairs --- http_config eval: $::HttpConfig --- config @@ -136,4 +142,4 @@ found 2 anotherdomain.com "6 13,13,13,15,16,17," --- no_error_log -[error] \ No newline at end of file +[error] diff --git a/t/openssl/x509/revoked.t b/t/openssl/x509/revoked.t index a60f3b7e5..ceb82b3b5 100644 --- a/t/openssl/x509/revoked.t +++ b/t/openssl/x509/revoked.t @@ -24,6 +24,7 @@ no_long_string(); run_tests(); __DATA__ + === TEST 1:revoked.new should create new revoked instance --- http_config eval: $::HttpConfig --- config @@ -47,6 +48,8 @@ __DATA__ --- no_error_log [error] + + === TEST 2:revoked.new should fail when invalid parameters are given --- http_config eval: $::HttpConfig --- config @@ -66,4 +69,4 @@ __DATA__ x509.revoked.new: sn should be number or a bn instance " --- no_error_log -[error] \ No newline at end of file +[error] diff --git a/t/openssl/x509/store.t b/t/openssl/x509/store.t index 16fd74c17..9f1618d09 100644 --- a/t/openssl/x509/store.t +++ b/t/openssl/x509/store.t @@ -23,6 +23,7 @@ our $HttpConfig = qq{ run_tests(); __DATA__ + === TEST 1: Creates store properly --- http_config eval: $::HttpConfig --- config @@ -40,6 +41,7 @@ __DATA__ [error] + === TEST 2: Loads a x509 object --- http_config eval: $::HttpConfig --- config @@ -59,6 +61,8 @@ __DATA__ --- no_error_log [error] + + === TEST 3: Loads default location --- http_config eval: $::HttpConfig --- config @@ -76,6 +80,8 @@ __DATA__ --- no_error_log [error] + + === TEST 4: Loads file --- http_config eval: $::HttpConfig --- config @@ -113,6 +119,7 @@ x509.store:load_file.+ [error] + === TEST 5: Verifies a x509 object --- http_config eval: $::HttpConfig --- config @@ -147,6 +154,7 @@ true [error] + === TEST 6: Using default CAs (skip due to hard to setup on custom-built openssl env) --- SKIP --- http_config eval: $::HttpConfig @@ -174,6 +182,8 @@ true --- no_error_log [error] + + === TEST 7: Loads directory --- http_config eval: $::HttpConfig --- config @@ -199,6 +209,8 @@ true --- no_error_log [error] + + === TEST 8: Verifies sub cert --- http_config eval: $::HttpConfig --- config @@ -237,6 +249,8 @@ B1BC968BD4F49D622AA89A81F2150152A41D829C --- no_error_log [error] + + === TEST 9: Set purpose --- http_config eval: $::HttpConfig --- config @@ -275,6 +289,8 @@ truenil --- no_error_log [error] + + === TEST 10: Set depth --- http_config eval: $::HttpConfig --- config @@ -309,6 +325,8 @@ nilcertificate chain too long --- no_error_log [error] + + === TEST 11: Verify with verify_method --- http_config eval: $::HttpConfig --- config @@ -348,6 +366,8 @@ nil(?:unsupported|unsuitable) certificate purpose --- no_error_log [error] + + === TEST 12: Set flags --- http_config eval: $::HttpConfig --- config @@ -380,6 +400,8 @@ truenil --- no_error_log [error] + + === TEST 13: Set verify time flags --- http_config eval: $::HttpConfig --- config @@ -411,6 +433,8 @@ truenil --- no_error_log [error] + + === TEST 14: Check revocation --- http_config eval: $::HttpConfig --- config @@ -467,4 +491,3 @@ nilcertificate revoked " --- no_error_log [error] - From d1d82aa300edf82ee6403459167ab98e17b6f8a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophile=20Diot?= Date: Fri, 29 Dec 2023 16:15:08 +0000 Subject: [PATCH 07/11] Add UI tests for the profile page and the Wizard --- tests/ui/docker-compose.dev.yml | 12 +- tests/ui/docker-compose.yml | 12 +- tests/ui/main.py | 308 ++++++++++++++++++++++++++++++-- tests/ui/requirements.in | 1 + tests/ui/requirements.txt | 4 + 5 files changed, 306 insertions(+), 31 deletions(-) diff --git a/tests/ui/docker-compose.dev.yml b/tests/ui/docker-compose.dev.yml index 817142cb4..c7b5d6db1 100644 --- a/tests/ui/docker-compose.dev.yml +++ b/tests/ui/docker-compose.dev.yml @@ -7,9 +7,8 @@ services: dockerfile: src/bw/Dockerfile ports: - 80:80 - - 443:8443 environment: - SERVER_NAME: "www.example.com" + SERVER_NAME: "" MULTISITE: "yes" HTTP_PORT: "80" API_WHITELIST_IP: "127.0.0.0/8 10.20.30.0/24" @@ -20,12 +19,7 @@ services: USE_CLIENT_CACHE: "yes" USE_GZIP: "yes" DATASTORE_MEMORY_SIZE: "384m" - www.example.com_USE_UI: "yes" - www.example.com_SERVE_FILES: "no" - www.example.com_USE_REVERSE_PROXY: "yes" - www.example.com_REVERSE_PROXY_URL: "/admin" - www.example.com_REVERSE_PROXY_HOST: "http://bw-ui:7000" - www.example.com_INTERCEPTED_ERROR_CODES: "400 405 413 429 500 501 502 503 504" + UI_HOST: "http://bw-ui:7000" labels: - "bunkerweb.INSTANCE=yes" networks: @@ -57,8 +51,6 @@ services: volumes: - bw-data:/data environment: - ADMIN_USERNAME: "admin" - ADMIN_PASSWORD: "S$$cr3tP@ssw0rd" DOCKER_HOST: "tcp://docker-proxy:2375" networks: - net-docker diff --git a/tests/ui/docker-compose.yml b/tests/ui/docker-compose.yml index 22c45d46c..302c8b6e8 100644 --- a/tests/ui/docker-compose.yml +++ b/tests/ui/docker-compose.yml @@ -6,9 +6,8 @@ services: pull_policy: never ports: - 80:80 - - 443:8443 environment: - SERVER_NAME: "www.example.com" + SERVER_NAME: "" MULTISITE: "yes" HTTP_PORT: "80" API_WHITELIST_IP: "127.0.0.0/8 10.20.30.0/24" @@ -20,13 +19,8 @@ services: USE_CLIENT_CACHE: "yes" USE_GZIP: "yes" DATASTORE_MEMORY_SIZE: "384m" - www.example.com_USE_UI: "yes" - www.example.com_SERVE_FILES: "no" - www.example.com_USE_REVERSE_PROXY: "yes" - www.example.com_REVERSE_PROXY_URL: "/admin" - www.example.com_REVERSE_PROXY_HOST: "http://bw-ui:7000" - www.example.com_INTERCEPTED_ERROR_CODES: "400 405 413 429 500 501 502 503 504" CUSTOM_CONF_SERVER_HTTP_port-redirect: "port_in_redirect on;" + UI_HOST: "http://bw-ui:7000" labels: - "bunkerweb.INSTANCE=yes" networks: @@ -54,8 +48,6 @@ services: - bw - bw-docker-proxy environment: - ADMIN_USERNAME: "admin" - ADMIN_PASSWORD: "S$$cr3tP@ssw0rd" DOCKER_HOST: "tcp://bw-docker-proxy:2375" volumes: - bw-data:/data diff --git a/tests/ui/main.py b/tests/ui/main.py index fcb580949..48fc8a9b4 100644 --- a/tests/ui/main.py +++ b/tests/ui/main.py @@ -7,6 +7,7 @@ from pathlib import Path from time import sleep from traceback import format_exc from typing import List, Union +from pyotp import TOTP from requests import get from requests.exceptions import RequestException from selenium import webdriver @@ -23,7 +24,7 @@ ready = False retries = 0 while not ready: with suppress(RequestException): - status_code = get("http://www.example.com/admin/login").status_code + status_code = get("http://127.0.0.1/setup").status_code if status_code > 500 and status_code != 502: print("An error occurred with the server, exiting ...", flush=True) @@ -178,9 +179,41 @@ with driver_func() as driver: driver.maximize_window() driver_wait = WebDriverWait(driver, 60) - print("Navigating to http://www.example.com/admin/login ...", flush=True) + print("Navigating to http://127.0.0.1/setup ...", flush=True) - driver.get("http://www.example.com/admin/login") + driver.get("http://127.0.0.1/setup") + + ### WIZARD PAGE + + try: + title = driver_wait.until(EC.presence_of_element_located((By.XPATH, "/html/body/main/div/div/h1"))) + + if title.text != "Setup Wizard": + print("Didn't get redirected to setup page, exiting ...", flush=True) + exit(1) + except TimeoutException: + print("Didn't get redirected to setup page, exiting ...", flush=True) + exit(1) + + print("Setup page loaded successfully, filling the form ...", flush=True) + + admin_username_input = safe_get_element(driver, By.ID, "admin_username") + password_input = safe_get_element(driver, By.ID, "admin_password") + password_check_input = safe_get_element(driver, By.ID, "admin_password_check") + ui_url = safe_get_element(driver, By.ID, "ui_url").get_attribute("value") + + admin_username_input.send_keys("admin") + password_input.send_keys("S$cr3tP@ssw0rd") + password_check_input.send_keys("S$cr3tP@ssw0rd") + + assert_button_click(driver, "//button[@id='setup-button']") + + print("Submitted the form, waiting for the wizard to finish ...", flush=True) + + current_time = datetime.now() + + while current_time + timedelta(minutes=5) > datetime.now() and not driver.current_url.endswith("/login"): + sleep(1) ### LOGIN PAGE @@ -197,7 +230,7 @@ with driver_func() as driver: flush=True, ) - driver.get("http://www.example.com/admin/home") + driver.get(f"http://www.example.com{ui_url}/home") print("Waiting for toast ...", flush=True) @@ -508,9 +541,9 @@ with driver_func() as driver: print("The service is not present, exiting ...", flush=True) exit(1) - if service.find_element(By.TAG_NAME, "h6").text.strip() != "scheduler": + if service.find_element(By.TAG_NAME, "h6").text.strip() != "ui": print( - "The service should have been created by the scheduler, exiting ...", + "The service should have been created by the ui, exiting ...", flush=True, ) exit(1) @@ -1260,8 +1293,8 @@ location /hello { current_date = datetime.now() resp = get( - f"http://www.example.com/admin/logs/{first_instance}?from_date={int(current_date.timestamp() - 86400000)}&to_date={int((current_date - timedelta(days=1)).timestamp())}", - headers={"Host": "www.example.com"}, + f"http://www.example.com{ui_url}/logs/{first_instance}?from_date={int(current_date.timestamp() - 86400000)}&to_date={int((current_date - timedelta(days=1)).timestamp())}", + headers={"Host": "www.example.com", "User-Agent": driver.execute_script("return navigator.userAgent;")}, cookies={"session": driver.get_cookies()[0]["value"]}, ) @@ -1396,13 +1429,173 @@ location /hello { sleep(0.3) - resp = get("http://www.example.com/admin/jobs/download?job_name=mmdb-country&file_name=country.mmdb") + resp = get(f"http://www.example.com{ui_url}/jobs/download?job_name=mmdb-country&file_name=country.mmdb") if resp.status_code != 200: print("The cache download is not working, exiting ...", flush=True) exit(1) - print("Cache download is working, trying to log out ...", flush=True) + print("Cache download is working, trying profile page ...", flush=True) + + access_page(driver, driver_wait, "/html/body/aside[1]/div[1]/div[2]/ul/li[10]/a", "profile") + + ### PROFILE PAGE + + username_input = safe_get_element(driver, By.ID, "admin_username") + + if username_input.get_attribute("value") != "admin": + print("The username is not correct, exiting ...", flush=True) + exit(1) + + username_input.clear() + username_input.send_keys("admin2") + + password_input = safe_get_element(driver, By.ID, "curr_password") + + if password_input.get_attribute("value") != "": + print("The current password is not empty, exiting ...", flush=True) + exit(1) + + password_input.send_keys("S$cr3tP@ssw0rd") + + assert_button_click(driver, "//button[@id='profile-button' and @class='edit-btn']") + + try: + title = driver_wait.until(EC.presence_of_element_located((By.XPATH, "/html/body/main/div[1]/div/h1"))) + + if title.text != "Log in": + print("Didn't get redirected to login page, exiting ...", flush=True) + exit(1) + except TimeoutException: + print("Login page didn't load in time, exiting ...", flush=True) + exit(1) + + print("Successfully changed username, trying to log in with new username ...", flush=True) + + username_input = safe_get_element(driver, By.ID, "username") + password_input = safe_get_element(driver, By.ID, "password") + username_input.send_keys("admin2") + password_input.send_keys("S$cr3tP@ssw0rd") + + access_page( + driver, + driver_wait, + "//button[@value='login']", + "profile", + ) + + username_input = safe_get_element(driver, By.ID, "admin_username") + + if username_input.get_attribute("value") != "admin2": + print("The username is not correct, exiting ...", flush=True) + exit(1) + + print("Successfully logged in with new username, trying to change password ...", flush=True) + + password_input = safe_get_element(driver, By.ID, "curr_password") + + if password_input.get_attribute("value") != "": + print("The current password is not empty, exiting ...", flush=True) + exit(1) + + password_input.send_keys("S$cr3tP@ssw0rd") + + new_password_input = safe_get_element(driver, By.ID, "admin_password") + + if new_password_input.get_attribute("value") != "": + print("The new password is not empty, exiting ...", flush=True) + exit(1) + + new_password_input.send_keys("P@ssw0rd") + + new_password_check_input = safe_get_element(driver, By.ID, "admin_password_check") + + if new_password_check_input.get_attribute("value") != "": + print("The new password check is not empty, exiting ...", flush=True) + exit(1) + + new_password_check_input.send_keys("P@ssw0rd") + + assert_button_click(driver, "//button[@id='profile-button' and @class='edit-btn']") + + try: + title = driver_wait.until(EC.presence_of_element_located((By.XPATH, "/html/body/main/div[1]/div/h1"))) + + if title.text != "Log in": + print("Didn't get redirected to login page, exiting ...", flush=True) + exit(1) + except TimeoutException: + print("Login page didn't load in time, exiting ...", flush=True) + exit(1) + + print("Successfully changed username, trying to log in with new password ...", flush=True) + + username_input = safe_get_element(driver, By.ID, "username") + password_input = safe_get_element(driver, By.ID, "password") + username_input.send_keys("admin2") + password_input.send_keys("P@ssw0rd") + + access_page( + driver, + driver_wait, + "//button[@value='login']", + "profile", + ) + + print("Successfully logged in with new password, trying 2FA ...", flush=True) + + assert_button_click(driver, "//button[@data-tab-handler='totp']") + + secret_token_input = safe_get_element(driver, By.ID, "secret_token") + secret_token = secret_token_input.get_attribute("value") + + driver.refresh() + + driver_wait.until(EC.presence_of_element_located((By.XPATH, "/html/body/div/header/div/nav/h6"))) + + assert_button_click(driver, "//button[@data-tab-handler='totp']") + + secret_token_input = safe_get_element(driver, By.ID, "secret_token") + new_secret_token = secret_token_input.get_attribute("value") + + if new_secret_token == secret_token: + print("The secret token hasn't been changed, exiting ...", flush=True) + exit(1) + + print("The secret token has been changed, trying to activate 2FA ...", flush=True) + + totp = TOTP(new_secret_token) + totp_input = safe_get_element(driver, By.ID, "totp_token") + totp_input.send_keys(totp.now()) + + password_input = safe_get_element(driver, By.ID, "totp_password") + + if password_input.get_attribute("value") != "": + print("The new password check is not empty, exiting ...", flush=True) + exit(1) + + password_input.send_keys("P@ssw0rd") + + access_page( + driver, + driver_wait, + "//button[@id='profile-button' and @class='valid-btn']", + "profile", + ) + + assert_button_click(driver, "//button[@data-tab-handler='totp']") + + try: + totp_state = safe_get_element(driver, By.XPATH, "/html/body/main/div/div/form[2]/h5") + + if totp_state.text != "TOTP IS CURRENTLY ON": + print("TOTP is not activated, exiting ...", flush=True) + exit(1) + except TimeoutException: + print("TOTP has not been activated, exiting ...", flush=True) + exit(1) + + print("2FA has been activated, trying to log out ...", flush=True) assert_button_click(driver, "//a[@href='logout']") @@ -1416,7 +1609,100 @@ location /hello { print("Login page didn't load in time, exiting ...", flush=True) exit(1) - print("Successfully logged out, tests are done", flush=True) + print("Successfully logged out, trying to log in with 2FA ...", flush=True) + + username_input = safe_get_element(driver, By.ID, "username") + password_input = safe_get_element(driver, By.ID, "password") + username_input.send_keys("admin2") + password_input.send_keys("P@ssw0rd") + + assert_button_click(driver, "//button[@value='login']") + + try: + totp_input = safe_get_element(driver, By.ID, "totp_token") + except TimeoutException: + print("Didn't get redirected to 2FA page, exiting ...", flush=True) + exit(1) + + totp_input.send_keys("0000000") + assert_button_click(driver, "//button[@value='login']") + + sleep(5) + + if not driver.current_url.endswith("/totp"): + print("Didn't get redirected back to 2FA page, exiting ...", flush=True) + exit(1) + + totp_input = safe_get_element(driver, By.ID, "totp_token") + totp_input.send_keys(totp.now()) + + access_page( + driver, + driver_wait, + "//button[@value='login']", + "home", + ) + + print("Successfully logged in with 2FA, trying to deactivate 2FA ...", flush=True) + + access_page(driver, driver_wait, "/html/body/aside[1]/div[1]/div[2]/ul/li[10]/a", "profile") + + assert_button_click(driver, "//button[@data-tab-handler='totp']") + + totp_input = safe_get_element(driver, By.ID, "totp_token") + totp_input.send_keys(totp.now()) + + password_input = safe_get_element(driver, By.ID, "totp_password") + password_input.send_keys("P@ssw0rd") + + access_page( + driver, + driver_wait, + "//button[@id='profile-button' and @class='delete-btn']", + "profile", + ) + + assert_button_click(driver, "//button[@data-tab-handler='totp']") + + try: + totp_state = safe_get_element(driver, By.XPATH, "/html/body/main/div/div/form[2]/h5") + + if totp_state.text != "TOTP IS CURRENTLY OFF": + print("TOTP is not deactivated, exiting ...", flush=True) + exit(1) + except TimeoutException: + print("TOTP has not been deactivated, exiting ...", flush=True) + exit(1) + + print("2FA has been deactivated, trying to log out ...", flush=True) + + assert_button_click(driver, "//a[@href='logout']") + + try: + title = driver_wait.until(EC.presence_of_element_located((By.XPATH, "/html/body/main/div[1]/div/h1"))) + + if title.text != "Log in": + print("Didn't get redirected to login page, exiting ...", flush=True) + exit(1) + except TimeoutException: + print("Login page didn't load in time, exiting ...", flush=True) + exit(1) + + print("Successfully logged out, trying to log in without 2FA ...", flush=True) + + username_input = safe_get_element(driver, By.ID, "username") + password_input = safe_get_element(driver, By.ID, "password") + username_input.send_keys("admin2") + password_input.send_keys("P@ssw0rd") + + access_page( + driver, + driver_wait, + "//button[@value='login']", + "home", + ) + + print("Successfully logged in without 2FA, tests are done, exiting ...", flush=True) except SystemExit: exit(1) except: diff --git a/tests/ui/requirements.in b/tests/ui/requirements.in index 49cb1341f..c215e69bd 100644 --- a/tests/ui/requirements.in +++ b/tests/ui/requirements.in @@ -1,2 +1,3 @@ +pyotp==2.9.0 requests==2.31.0 selenium==4.16.0 diff --git a/tests/ui/requirements.txt b/tests/ui/requirements.txt index 5569ddd33..99ddbd31e 100644 --- a/tests/ui/requirements.txt +++ b/tests/ui/requirements.txt @@ -128,6 +128,10 @@ outcome==1.3.0.post0 \ --hash=sha256:9dcf02e65f2971b80047b377468e72a268e15c0af3cf1238e6ff14f7f91143b8 \ --hash=sha256:e771c5ce06d1415e356078d3bdd68523f284b4ce5419828922b6871e65eda82b # via trio +pyotp==2.9.0 \ + --hash=sha256:346b6642e0dbdde3b4ff5a930b664ca82abfa116356ed48cc42c7d6590d36f63 \ + --hash=sha256:81c2e5865b8ac55e825b0358e496e1d9387c811e85bb40e71a3b29b288963612 + # via -r requirements.in pysocks==1.7.1 \ --hash=sha256:08e69f092cc6dbe92a0fdd16eeb9b9ffbc13cadfe5ca4c7bd92ffb078b293299 \ --hash=sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5 \ From 91448f1f45410b208e4160059164ca9ffcfd4113 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophile=20Diot?= Date: Fri, 29 Dec 2023 16:15:34 +0000 Subject: [PATCH 08/11] Add a log in the UI when a login attempt is made --- src/ui/main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ui/main.py b/src/ui/main.py index d10708124..e7d26309a 100755 --- a/src/ui/main.py +++ b/src/ui/main.py @@ -1660,6 +1660,7 @@ def jobs_download(): def login(): fail = False if request.method == "POST" and "username" in request.form and "password" in request.form: + app.logger.warning(f"Login attempt from {request.remote_addr} with username \"{request.form['username']}\"") if app.config["USER"].get_id() == request.form["username"] and app.config["USER"].check_password(request.form["password"]): # log the user in session["ip"] = request.remote_addr From fdb01b305949e82a0a80460206c6084497b334a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophile=20Diot?= Date: Fri, 29 Dec 2023 16:16:11 +0000 Subject: [PATCH 09/11] Fix shenanigans with the ui user edition --- src/common/db/Database.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/common/db/Database.py b/src/common/db/Database.py index 7b8f4c438..eafa92c47 100644 --- a/src/common/db/Database.py +++ b/src/common/db/Database.py @@ -1700,7 +1700,7 @@ class Database: return "" - def update_ui_user(self, username: str, password: bytes, is_two_factor_enabled: bool = False, secret_token: Optional[str] = None) -> str: + def update_ui_user(self, username: str, password: bytes, is_two_factor_enabled: bool = False, secret_token: Optional[str] = None, method: str = "ui") -> str: """Update ui user.""" with self.__db_session() as session: user = session.query(Users).filter_by(id=1).first() @@ -1711,6 +1711,7 @@ class Database: user.password = password.decode("utf-8") user.is_two_factor_enabled = is_two_factor_enabled user.secret_token = secret_token + user.method = method try: session.commit() From a5e0ceed3be78085e9b85dc40714b89309c32be4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophile=20Diot?= Date: Fri, 29 Dec 2023 16:16:58 +0000 Subject: [PATCH 10/11] [#795] Add setting REVERSE_PROXY_INCLUDES to manually add "include" directives in the reverse proxies --- .../reverseproxy/confs/server-http/reverse-proxy.conf | 6 ++++++ src/common/core/reverseproxy/plugin.json | 10 ++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/common/core/reverseproxy/confs/server-http/reverse-proxy.conf b/src/common/core/reverseproxy/confs/server-http/reverse-proxy.conf index 2024cac6c..e39a58697 100644 --- a/src/common/core/reverseproxy/confs/server-http/reverse-proxy.conf +++ b/src/common/core/reverseproxy/confs/server-http/reverse-proxy.conf @@ -38,6 +38,7 @@ add_header X-Proxy-Cache $upstream_cache_status; {% set connect_timeout = all[k.replace("URL", "CONNECT_TIMEOUT")] if k.replace("URL", "CONNECT_TIMEOUT") in all else "60s" %} {% set read_timeout = all[k.replace("URL", "READ_TIMEOUT")] if k.replace("URL", "READ_TIMEOUT") in all else "60s" %} {% set send_timeout = all[k.replace("URL", "SEND_TIMEOUT")] if k.replace("URL", "SEND_TIMEOUT") in all else "60s" %} + {% set includes = all[k.replace("URL", "INCLUDES")] if k.replace("URL", "INCLUDES") in all else "" %} location {{ url }} {% raw %}{{% endraw +%} etag off; set $backend{{ counter.value }} "{{ host }}"; @@ -88,6 +89,11 @@ location {{ url }} {% raw %}{{% endraw +%} proxy_connect_timeout {{ connect_timeout }}; proxy_read_timeout {{ read_timeout }}; proxy_send_timeout {{ send_timeout }}; + {% if includes != "" +%} + {% for include in includes.split(" ") +%} + include {{ include }}; + {% endfor +%} + {% endif +%} {% raw %}}{% endraw %} {% endif %} {% set counter.value = counter.value + 1 %} diff --git a/src/common/core/reverseproxy/plugin.json b/src/common/core/reverseproxy/plugin.json index c28e668ec..846628c3c 100644 --- a/src/common/core/reverseproxy/plugin.json +++ b/src/common/core/reverseproxy/plugin.json @@ -242,6 +242,16 @@ "regex": "^\\d+(ms?|[shdwMy])$", "type": "text", "multiple": "reverse-proxy" + }, + "REVERSE_PROXY_INCLUDES": { + "context": "multisite", + "default": "", + "help": "Additional configuration to include in the location block, separated with spaces.", + "id": "reverse-proxy-includes", + "label": "Reverse proxy includes", + "regex": "^(?! )( ?(\\w+)(?!.*\\b\\2\\b))*$", + "type": "text", + "multiple": "reverse-proxy" } } } From aea3fae2ba397d03d1f39016df5169acb9fb7ce1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophile=20Diot?= Date: Fri, 29 Dec 2023 16:17:22 +0000 Subject: [PATCH 11/11] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b787474c8..c46b36878 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ - [FEATURE] Add Anonymous reporting feature - [FEATURE] Add support for fallback Referrer-Policies - [FEATURE] Add profile page to web ui and the possibility to activate the 2FA +- [FEATURE] Add setting REVERSE_PROXY_INCLUDES to manually add "include" directives in the reverse proxies - [MISC] Fallback to default HTTPS certificate to prevent errors - [MISC] Updated Python Docker image to 3.12.1-alpine3.18 in Dockerfiles - [DEPS] Updated ModSecurity to v3.0.11