diff --git a/.github/workflows/lua-base64.yml b/.github/workflows/lua-base64.yml new file mode 100644 index 00000000..8d9fc173 --- /dev/null +++ b/.github/workflows/lua-base64.yml @@ -0,0 +1,202 @@ +name: lua-base64 + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +on: + workflow_dispatch: + pull_request: + paths: + - '.github/workflows/lua-base64.yml' + - 'dependencies/lua-base64/**' + push: + branches: + - develop + - master + paths: + - '.github/workflows/lua-base64.yml' + - 'dependencies/lua-base64/**' + +jobs: + dependency-scan: + uses: centreon/security-tools/.github/workflows/dependency-analysis.yml@main + + get-environment: + needs: [dependency-scan] + uses: ./.github/workflows/get-environment.yml + + package: + needs: [get-environment] + + strategy: + fail-fast: false + matrix: + distrib: [el8, el9, el10, bullseye, bookworm, trixie, jammy, noble] + include: + - package_extension: rpm + image: packaging-stream-connectors-nfpm-alma8 + distrib: el8 + - package_extension: rpm + image: packaging-stream-connectors-nfpm-alma9 + distrib: el9 + - package_extension: rpm + image: packaging-stream-connectors-nfpm-alma10 + distrib: el10 + - package_extension: deb + image: packaging-stream-connectors-nfpm-bullseye + distrib: bullseye + - package_extension: deb + image: packaging-stream-connectors-nfpm-bookworm + distrib: bookworm + - package_extension: deb + image: packaging-stream-connectors-nfpm-trixie + distrib: trixie + - package_extension: deb + image: packaging-stream-connectors-nfpm-jammy + distrib: jammy + - package_extension: deb + image: packaging-stream-connectors-nfpm-noble + distrib: noble + + runs-on: ubuntu-24.04 + + container: + image: ${{ vars.DOCKER_INTERNAL_REGISTRY_URL }}/${{ matrix.image }}:latest + credentials: + username: ${{ secrets.HARBOR_CENTREON_PULL_USERNAME }} + password: ${{ secrets.HARBOR_CENTREON_PULL_TOKEN }} + + name: package ${{ matrix.distrib }} + + steps: + - name: Checkout sources + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Checkout base64 sources + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + repository: "iskolbin/lbase64" + path: "base64-src" + ref: "c261320edbdf82c16409d893a96c28c704aa0ab8" # v1.5.3 + + - name: Prepare packaging of lua-base64 + run: | + mkdir -p dependencies/lua-base64/lbase64 + cp base64-src/base64.lua dependencies/lua-base64/lbase64/base64.lua + shell: bash + + - name: Package + uses: ./.github/actions/package-nfpm + with: + nfpm_file_pattern: "dependencies/lua-base64/packaging/*.yaml" + distrib: ${{ matrix.distrib }} + package_extension: ${{ matrix.package_extension }} + arch: all + version: "1.5.3" + release: "1" + commit_hash: ${{ github.sha }} + cache_key: ${{ github.sha }}-${{ github.run_id }}-${{ matrix.package_extension }}-lua-base64-${{ matrix.distrib }} + rpm_gpg_key: ${{ secrets.RPM_GPG_SIGNING_KEY }} + rpm_gpg_signing_key_id: ${{ secrets.RPM_GPG_SIGNING_KEY_ID }} + rpm_gpg_signing_passphrase: ${{ secrets.RPM_GPG_SIGNING_PASSPHRASE }} + stability: ${{ needs.get-environment.outputs.stability }} + artifact_name: "package-lua-base64-${{ matrix.distrib }}" + + test-packages: + needs: [get-environment, package] + strategy: + fail-fast: false + matrix: + include: + - package_extension: rpm + image: almalinux:8 + distrib: el8 + - package_extension: rpm + image: almalinux:9 + distrib: el9 + - package_extension: rpm + image: almalinux:10 + distrib: el10 + - package_extension: deb + image: debian:bullseye + distrib: bullseye + - package_extension: deb + image: debian:bookworm + distrib: bookworm + - package_extension: deb + image: debian:trixie + distrib: trixie + - package_extension: deb + image: ubuntu:jammy + distrib: jammy + - package_extension: deb + image: ubuntu:noble + distrib: noble + + runs-on: ubuntu-24.04 + container: + image: ${{ matrix.image }} + + name: Test lua packages on ${{ matrix.package_extension }} ${{ matrix.distrib }} + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Test packaged libs + uses: ./.github/actions/test-packages + with: + package_extension: ${{ matrix.package_extension }} + distrib: ${{ matrix.distrib }} + cache_key: ${{ github.sha }}-${{ github.run_id }}-${{ matrix.package_extension }}-lua-base64-${{ matrix.distrib }} + test_type: dependency + + - name: Upload error log + if: failure() + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + with: + name: install_error_log_${{ matrix.distrib }} + path: install_error_${{ matrix.distrib }}.log + + deliver-rpm: + if: ${{ contains(fromJson('["unstable", "testing", "stable"]'), needs.get-environment.outputs.stability) }} + needs: [get-environment, package, test-packages] + runs-on: ubuntu-24.04 + strategy: + matrix: + distrib: [el8, el9, el10] + name: deliver ${{ matrix.distrib }} + + steps: + - name: Checkout sources + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Publish RPM packages + uses: ./.github/actions/rpm-delivery + with: + module_name: lua-base64 + distrib: ${{ matrix.distrib }} + artifactory_token: ${{ secrets.ARTIFACTORY_ACCESS_TOKEN }} + cache_key: ${{ github.sha }}-${{ github.run_id }}-rpm-lua-base64-${{ matrix.distrib }} + stability: ${{ needs.get-environment.outputs.stability }} + + deliver-deb: + if: ${{ contains(fromJson('["unstable", "testing", "stable"]'), needs.get-environment.outputs.stability) }} + needs: [get-environment, package, test-packages] + runs-on: ubuntu-24.04 + strategy: + matrix: + distrib: [bullseye, bookworm, trixie, jammy, noble] + name: deliver ${{ matrix.distrib }} + + steps: + - name: Checkout sources + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Publish DEB packages + uses: ./.github/actions/deb-delivery + with: + module_name: lua-base64 + distrib: ${{ matrix.distrib }} + artifactory_token: ${{ secrets.ARTIFACTORY_ACCESS_TOKEN }} + cache_key: ${{ github.sha }}-${{ github.run_id }}-deb-lua-base64-${{ matrix.distrib }} + stability: ${{ needs.get-environment.outputs.stability }} diff --git a/.github/workflows/lua-openssl.yml b/.github/workflows/lua-openssl.yml new file mode 100644 index 00000000..132f1e78 --- /dev/null +++ b/.github/workflows/lua-openssl.yml @@ -0,0 +1,233 @@ +name: lua-openssl + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +on: + workflow_dispatch: + pull_request: + paths: + - '.github/workflows/lua-openssl.yml' + - 'dependencies/lua-openssl/**' + push: + branches: + - develop + - master + paths: + - '.github/workflows/lua-openssl.yml' + - 'dependencies/lua-openssl/**' + +jobs: + dependency-scan: + uses: centreon/security-tools/.github/workflows/dependency-analysis.yml@main + + get-environment: + needs: [dependency-scan] + uses: ./.github/workflows/get-environment.yml + + package: + needs: [get-environment] + + strategy: + fail-fast: false + matrix: + distrib: [el8, el9, el10, bullseye, bookworm, trixie, jammy, noble] + include: + - package_extension: rpm + image: packaging-stream-connectors-nfpm-alma8 + distrib: el8 + - package_extension: rpm + image: packaging-stream-connectors-nfpm-alma9 + distrib: el9 + - package_extension: rpm + image: packaging-stream-connectors-nfpm-alma10 + distrib: el10 + - package_extension: deb + image: packaging-stream-connectors-nfpm-bullseye + distrib: bullseye + - package_extension: deb + image: packaging-stream-connectors-nfpm-bookworm + distrib: bookworm + - package_extension: deb + image: packaging-stream-connectors-nfpm-trixie + distrib: trixie + - package_extension: deb + image: packaging-stream-connectors-nfpm-jammy + distrib: jammy + - package_extension: deb + image: packaging-stream-connectors-nfpm-noble + distrib: noble + + runs-on: ubuntu-24.04 + + container: + image: ${{ vars.DOCKER_INTERNAL_REGISTRY_URL }}/${{ matrix.image }}:latest + credentials: + username: ${{ secrets.HARBOR_CENTREON_PULL_USERNAME }} + password: ${{ secrets.HARBOR_CENTREON_PULL_TOKEN }} + + name: package ${{ matrix.distrib }} + + steps: + - name: Checkout sources + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Install dependencies + env: + PACKAGE_EXTENSION: ${{ matrix.package_extension }} + DISTRIB: ${{ matrix.distrib }} + run: | + if [ "$PACKAGE_EXTENSION" = "rpm" ]; then + dnf install -y cmake gcc openssl-devel lua-devel + else + apt-get update + apt-get install -y cmake gcc libssl-dev + if [ "$DISTRIB" = "trixie" ]; then + apt-get install -y liblua5.4-dev + else + apt-get install -y liblua5.3-dev + fi + fi + shell: bash + + - name: Checkout lua-openssl sources + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + repository: "zhaozg/lua-openssl" + path: "lua-openssl-src" + ref: "9642d3bff600d0d12e4c24b4059dd331655042bd" # 0.11.1-1 + submodules: true + + - name: Prepare packaging of lua-openssl + env: + DISTRIB: ${{ matrix.distrib }} + run: | + cd lua-openssl-src + if [[ "$DISTRIB" = "el9" || "$DISTRIB" = "el10" || "$DISTRIB" = "trixie" ]]; then + lua_version=5.4 + else + lua_version=5.3 + fi + mkdir -p build && cd build + cmake .. -DLUA_VERSION=${lua_version} + make + cd ../.. + mkdir -p dependencies/lua-openssl/lua-openssl + cp lua-openssl-src/build/openssl.so dependencies/lua-openssl/lua-openssl/ + shell: bash + + - name: Package + uses: ./.github/actions/package-nfpm + with: + nfpm_file_pattern: "dependencies/lua-openssl/packaging/*.yaml" + distrib: ${{ matrix.distrib }} + package_extension: ${{ matrix.package_extension }} + arch: amd64 + version: "0.11.1" + release: "1" + commit_hash: ${{ github.sha }} + cache_key: ${{ github.sha }}-${{ github.run_id }}-${{ matrix.package_extension }}-lua-openssl-${{ matrix.distrib }} + rpm_gpg_key: ${{ secrets.RPM_GPG_SIGNING_KEY }} + rpm_gpg_signing_key_id: ${{ secrets.RPM_GPG_SIGNING_KEY_ID }} + rpm_gpg_signing_passphrase: ${{ secrets.RPM_GPG_SIGNING_PASSPHRASE }} + stability: ${{ needs.get-environment.outputs.stability }} + artifact_name: "package-lua-openssl-${{ matrix.distrib }}" + + test-packages: + needs: [get-environment, package] + strategy: + fail-fast: false + matrix: + include: + - package_extension: rpm + image: almalinux:8 + distrib: el8 + - package_extension: rpm + image: almalinux:9 + distrib: el9 + - package_extension: rpm + image: almalinux:10 + distrib: el10 + - package_extension: deb + image: debian:bullseye + distrib: bullseye + - package_extension: deb + image: debian:bookworm + distrib: bookworm + - package_extension: deb + image: debian:trixie + distrib: trixie + - package_extension: deb + image: ubuntu:jammy + distrib: jammy + - package_extension: deb + image: ubuntu:noble + distrib: noble + + runs-on: ubuntu-24.04 + container: + image: ${{ matrix.image }} + + name: Test lua packages on ${{ matrix.package_extension }} ${{ matrix.distrib }} + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Test packaged libs + uses: ./.github/actions/test-packages + with: + package_extension: ${{ matrix.package_extension }} + distrib: ${{ matrix.distrib }} + cache_key: ${{ github.sha }}-${{ github.run_id }}-${{ matrix.package_extension }}-lua-openssl-${{ matrix.distrib }} + test_type: dependency + + - name: Upload error log + if: failure() + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + with: + name: install_error_log_${{ matrix.distrib }} + path: install_error_${{ matrix.distrib }}.log + + deliver-rpm: + if: ${{ contains(fromJson('["unstable", "testing", "stable"]'), needs.get-environment.outputs.stability) }} + needs: [get-environment, package, test-packages] + runs-on: ubuntu-24.04 + strategy: + matrix: + distrib: [el8, el9, el10] + name: deliver ${{ matrix.distrib }} + + steps: + - name: Checkout sources + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Publish RPM packages + uses: ./.github/actions/rpm-delivery + with: + module_name: lua-openssl + distrib: ${{ matrix.distrib }} + artifactory_token: ${{ secrets.ARTIFACTORY_ACCESS_TOKEN }} + cache_key: ${{ github.sha }}-${{ github.run_id }}-rpm-lua-openssl-${{ matrix.distrib }} + stability: ${{ needs.get-environment.outputs.stability }} + + deliver-deb: + if: ${{ contains(fromJson('["unstable", "testing", "stable"]'), needs.get-environment.outputs.stability) }} + needs: [get-environment, package, test-packages] + runs-on: ubuntu-24.04 + strategy: + matrix: + distrib: [bullseye, bookworm, trixie, jammy, noble] + name: deliver ${{ matrix.distrib }} + + steps: + - name: Checkout sources + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Publish DEB packages + uses: ./.github/actions/deb-delivery + with: + module_name: lua-openssl + distrib: ${{ matrix.distrib }} + artifactory_token: ${{ secrets.ARTIFACTORY_ACCESS_TOKEN }} + cache_key: ${{ github.sha }}-${{ github.run_id }}-deb-lua-openssl-${{ matrix.distrib }} + stability: ${{ needs.get-environment.outputs.stability }} diff --git a/dependencies/lua-base64/packaging/lua-base64.yaml b/dependencies/lua-base64/packaging/lua-base64.yaml new file mode 100644 index 00000000..05a8817c --- /dev/null +++ b/dependencies/lua-base64/packaging/lua-base64.yaml @@ -0,0 +1,38 @@ +name: "lua-base64" +arch: "${ARCH}" +platform: "linux" +version_schema: "none" +version: "${VERSION}" +release: "${RELEASE}${DIST}" +section: "default" +priority: "optional" +maintainer: "Centreon " +description: | + lua base64 encoder/decoder + Commit: @COMMIT_HASH@ +vendor: "Centreon" +homepage: "https://www.centreon.com" +license: "Apache-2.0" + +contents: + - src: "../lbase64/base64.lua" + dst: "/usr/share/lua/@luaver@/base64.lua" + packager: rpm + + - src: "../lbase64/base64.lua" + dst: "/usr/share/lua/@luaver@/base64.lua" + packager: deb + +overrides: + rpm: + depends: + - lua + deb: + depends: + - "lua@luaver@" + +rpm: + summary: lua base64 + signature: + key_file: ${RPM_SIGNING_KEY_FILE} + key_id: ${RPM_SIGNING_KEY_ID} diff --git a/dependencies/lua-openssl/packaging/lua-openssl.yaml b/dependencies/lua-openssl/packaging/lua-openssl.yaml new file mode 100644 index 00000000..aff92ae7 --- /dev/null +++ b/dependencies/lua-openssl/packaging/lua-openssl.yaml @@ -0,0 +1,40 @@ +name: "lua-openssl" +arch: "${ARCH}" +platform: "linux" +version_schema: "none" +version: "${VERSION}" +release: "${RELEASE}${DIST}" +section: "default" +priority: "optional" +maintainer: "Centreon " +description: | + lua OpenSSL binding library + Commit: @COMMIT_HASH@ +vendor: "Centreon" +homepage: "https://www.centreon.com" +license: "MIT" + +contents: + - src: "../lua-openssl/openssl.so" + dst: "/usr/lib64/lua/@luaver@/openssl.so" + packager: rpm + + - src: "../lua-openssl/openssl.so" + dst: "/usr/lib/x86_64-linux-gnu/lua/@luaver@/openssl.so" + packager: deb + +overrides: + rpm: + depends: + - lua + - openssl + deb: + depends: + - "lua@luaver@" + - "libssl3 | libssl1.1" + +rpm: + summary: lua OpenSSL binding + signature: + key_file: ${RPM_SIGNING_KEY_FILE} + key_id: ${RPM_SIGNING_KEY_ID} diff --git a/modules/centreon-stream-connectors-lib/google/auth/oauth.lua b/modules/centreon-stream-connectors-lib/google/auth/oauth.lua index af8ef79b..b7124761 100644 --- a/modules/centreon-stream-connectors-lib/google/auth/oauth.lua +++ b/modules/centreon-stream-connectors-lib/google/auth/oauth.lua @@ -7,7 +7,7 @@ local oauth = {} local mime = require("mime") -local crypto = require("crypto") +local openssl = require("openssl") local curl = require("cURL") local sc_common = require("centreon-stream-connectors-lib.sc_common") local sc_logger = require("centreon-stream-connectors-lib.sc_logger") @@ -163,25 +163,24 @@ end -- @return false (boolean) if the key object is not created using the private key from the key file or if the sign operation failed -- @return true (boolean) if the string has been successfully signed function OAuth:create_signature(string_to_sign) - -- create a pkey object - local private_key_object = crypto.pkey.from_pem(self.key_table.private_key, true) + -- create a pkey object from the PEM private key + local private_key_object = openssl.pkey.read(self.key_table.private_key, true) -- return if the pkey object is not valid if not private_key_object then - self.sc_logger:error("[google.auth.oauth:create_signature]: couldn't create private key object using crypto lib and" + self.sc_logger:error("[google.auth.oauth:create_signature]: couldn't create private key object using openssl lib and" .. " private key from key file " .. tostring(self.jwt_info.key_file)) return false end - -- sign the string - local signature = crypto.sign(self.jwt_info.hash_protocol, string_to_sign, private_key_object) + -- sign the string using RSA-SHA256 + local signature = private_key_object:sign(string_to_sign, "sha256") -- return if string is not signed if not signature then - self.sc_logger:error("[google.auth.oauth:create_signature]: couldn't sign string using crypto lib and the hash protocol: " - .. tostring(self.jwt_info.hash_protocol)) - + self.sc_logger:error("[google.auth.oauth:create_signature]: couldn't sign string using openssl lib with sha256") + return false end diff --git a/tests/packaging/dependencies/lua-base64.lua b/tests/packaging/dependencies/lua-base64.lua new file mode 100644 index 00000000..66a267e6 --- /dev/null +++ b/tests/packaging/dependencies/lua-base64.lua @@ -0,0 +1,92 @@ +#!/usr/bin/env lua + +-- Check if the module can be loaded +local status, base64 = pcall(require, 'base64') + +if not status then + print("ERROR: Unable to load base64 module") + print(base64) + os.exit(1) +end + +print("✓ base64 module loaded successfully") + +-- Test encoding of a known string +local encoded = base64.encode("Hello, World!") +if encoded ~= "SGVsbG8sIFdvcmxkIQ==" then + print("ERROR: Encoding failed") + print("Expected: SGVsbG8sIFdvcmxkIQ==") + print("Got: " .. tostring(encoded)) + os.exit(1) +end + +print("✓ Encoding successful") + +-- Test decoding of a known base64 string +local decoded = base64.decode("SGVsbG8sIFdvcmxkIQ==") +if decoded ~= "Hello, World!" then + print("ERROR: Decoding failed") + print("Expected: Hello, World!") + print("Got: " .. tostring(decoded)) + os.exit(1) +end + +print("✓ Decoding successful") + +-- Test encode/decode roundtrip +local original = "Centreon stream connector - lua-base64 test 1234!@#$" +local roundtrip = base64.decode(base64.encode(original)) +if roundtrip ~= original then + print("ERROR: Roundtrip encode/decode failed") + print("Expected: " .. original) + print("Got: " .. tostring(roundtrip)) + os.exit(1) +end + +print("✓ Roundtrip encode/decode successful") + +-- Test encoding of empty string +local encoded_empty = base64.encode("") +if encoded_empty ~= "" then + print("ERROR: Empty string encoding failed") + print("Expected: ''") + print("Got: " .. tostring(encoded_empty)) + os.exit(1) +end + +print("✓ Empty string encoding successful") + +-- Test decoding of empty string +local decoded_empty = base64.decode("") +if decoded_empty ~= "" then + print("ERROR: Empty string decoding failed") + print("Expected: ''") + print("Got: " .. tostring(decoded_empty)) + os.exit(1) +end + +print("✓ Empty string decoding successful") + +-- Test encoding of binary-like data (all byte values 0-255) +local binary_data = "" +for i = 0, 255 do + binary_data = binary_data .. string.char(i) +end + +local ok, err = pcall(function() + local enc = base64.encode(binary_data) + local dec = base64.decode(enc) + if dec ~= binary_data then + error("Binary roundtrip mismatch") + end +end) + +if not ok then + print("ERROR: Binary data roundtrip failed") + print(err) + os.exit(1) +end + +print("✓ Binary data roundtrip successful") + +print("\nAll tests passed - lua-base64 is working correctly!") diff --git a/tests/packaging/dependencies/lua-openssl.lua b/tests/packaging/dependencies/lua-openssl.lua new file mode 100644 index 00000000..3e36ecd8 --- /dev/null +++ b/tests/packaging/dependencies/lua-openssl.lua @@ -0,0 +1,136 @@ +#!/usr/bin/env lua + +-- Check if the module can be loaded +local status, openssl = pcall(require, 'openssl') + +if not status then + print("ERROR: Unable to load openssl module") + print(openssl) + os.exit(1) +end + +print("✓ openssl module loaded successfully") + +-- Test SHA256 digest computation +local ok, md = pcall(function() + return openssl.digest.new("sha256") +end) + +if not ok or not md then + print("ERROR: Unable to create sha256 digest context") + print(tostring(md)) + os.exit(1) +end + +md:update("test") +local hash = md:final() + +if not hash or #hash == 0 then + print("ERROR: SHA256 digest returned empty result") + os.exit(1) +end + +print("✓ SHA256 digest computation successful") + +-- Test RSA key generation, pkey.read and pkey:sign +-- These are the exact functions used in google/auth/oauth.lua:create_signature() +if not openssl.pkey or not openssl.pkey.read then + print("ERROR: openssl.pkey API not available") + os.exit(1) +end + +-- Try various key generation approaches and capture actual error messages +-- openssl.pkey.new returns nil, errmsg on failure (not a Lua exception) +local pk +local gen_errors = {} + +local gen_attempts = { + {label="pkey.new({type='rsa', bits=2048})", fn=function() return openssl.pkey.new({type='rsa', bits=2048}) end}, + {label="pkey.new({type='RSA', bits=2048})", fn=function() return openssl.pkey.new({type='RSA', bits=2048}) end}, + {label="pkey.new('rsa', 2048)", fn=function() return openssl.pkey.new('rsa', 2048) end}, + {label="pkey.new('RSA', 2048)", fn=function() return openssl.pkey.new('RSA', 2048) end}, +} + +-- Also try via openssl.rsa module if available +if type(openssl.rsa) == 'table' and type(openssl.rsa.generate) == 'function' then + table.insert(gen_attempts, { + label = "rsa.generate(2048) + pkey.read", + fn = function() + local rsa = openssl.rsa.generate(2048) + if not rsa then return nil, "rsa.generate returned nil" end + local pem = rsa:export('pem', true) + if not pem then pem = rsa:export() end + if not pem then return nil, "rsa export returned nil" end + return openssl.pkey.read(pem, true) + end + }) +end + +for _, attempt in ipairs(gen_attempts) do + -- Capture ok, first_return (pkey or nil), second_return (errmsg if nil) + local ok2, r1, r2 = pcall(attempt.fn) + if ok2 and r1 then + pk = r1 + break + else + local err = ok2 and tostring(r2) or tostring(r1) + table.insert(gen_errors, attempt.label .. ": " .. err) + end +end + +if not pk then + print("ERROR: Unable to generate RSA key pair") + for _, err in ipairs(gen_errors) do + print(" " .. err) + end + if type(openssl.pkey) == 'table' then + print(" Available openssl.pkey functions:") + for k in pairs(openssl.pkey) do + print(" pkey." .. k) + end + end + os.exit(1) +end + +print("✓ RSA key generation successful") + +-- Export to PEM, then reload with pkey.read (mirrors oauth.lua flow) +local pem +for _, args in ipairs({{"pem", true}, {}}) do + local eok, result = pcall(function() return pk:export(table.unpack(args)) end) + if eok and result and type(result) == "string" and result:match("BEGIN") then + pem = result + break + end +end + +if not pem then + print("ERROR: Unable to export private key to PEM") + os.exit(1) +end + +-- oauth.lua line: openssl.pkey.read(self.key_table.private_key, true) +local ok2, loaded_pk, load_err = pcall(openssl.pkey.read, pem, true) + +if not ok2 or not loaded_pk then + print("ERROR: openssl.pkey.read from PEM failed") + print(tostring(load_err or loaded_pk)) + os.exit(1) +end + +print("✓ openssl.pkey.read from PEM successful") + +-- oauth.lua line: private_key_object:sign(string_to_sign, "sha256") +local ok3, sig, sign_err = pcall(function() + return loaded_pk:sign("header.payload", "sha256") +end) + +if not ok3 or not sig or #sig == 0 then + print("ERROR: RSA-SHA256 signing failed") + print(tostring(sign_err or sig)) + os.exit(1) +end + +print("✓ RSA-SHA256 signing (pkey:sign) successful") + +print("\nAll tests passed - lua-openssl is working correctly!")