diff --git a/.cargo/config.toml b/.cargo/config.toml index a08d2f3..ea773f6 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,2 +1,3 @@ [env] OPENSSL_DIR = "C:\\Users\\bgrieder\\projects\\vcpkg_installed\\vcpkg\\pkgs\\openssl_x64-windows-static" +LIBCLANG_PATH = "C:\\Program Files\\LLVM\\bin" diff --git a/.github/scripts/build_ekm_dll.ps1 b/.github/scripts/build_ekm_dll.ps1 new file mode 100644 index 0000000..8101bf7 --- /dev/null +++ b/.github/scripts/build_ekm_dll.ps1 @@ -0,0 +1,64 @@ +$ErrorActionPreference = "Stop" +Set-StrictMode -Version Latest + +# --------------------------------------------------------------------------- +# Helper: run a native command, stream its output, and throw on non-zero exit. +# Works in both PS 5.1 and PS 7. +# --------------------------------------------------------------------------- +function Invoke-NativeCommand { + param( + [Parameter(Mandatory)][string] $Exe, + [Parameter(ValueFromRemainingArguments)][string[]] $Arguments + ) + $ErrorActionPreference = "Continue" + & $Exe @Arguments + if ($LASTEXITCODE -ne 0) { + throw "'$Exe $($Arguments -join ' ')' failed with exit code $LASTEXITCODE" + } +} + +function Build-EkmDll { + # ------------------------------------------------------------------------- + # Validate required environment variables + # ------------------------------------------------------------------------- + if (-not $env:OPENSSL_DIR) { + throw "OPENSSL_DIR is not set. Install OpenSSL via vcpkg --triplet x64-windows-static first." + } + if (-not (Test-Path $env:OPENSSL_DIR)) { + throw "OPENSSL_DIR does not exist: $env:OPENSSL_DIR" + } + if (-not $env:LIBCLANG_PATH) { + throw "LIBCLANG_PATH is not set. Required by build.rs (bindgen 0.71)." + } + + Write-Host "OPENSSL_DIR = $env:OPENSSL_DIR" + Write-Host "OPENSSL_STATIC = $env:OPENSSL_STATIC" + Write-Host "LIBCLANG_PATH = $env:LIBCLANG_PATH" + + # ------------------------------------------------------------------------- + # Ensure the MSVC Windows target is present + # ------------------------------------------------------------------------- + try { + Invoke-NativeCommand rustup target add x86_64-pc-windows-msvc + } + catch { + Write-Host "Note: $_ (target is likely already installed)" + } + + # ------------------------------------------------------------------------- + # Build the cdylib (DLL only; --lib skips the generate-certs binary) + # ------------------------------------------------------------------------- + Invoke-NativeCommand cargo build --release --lib + + $dll = "target\release\cosmian_ekm_sql_server.dll" + if (-not (Test-Path $dll)) { + throw "Expected DLL not found after build: $dll" + } + + $item = Get-Item $dll + Write-Host "" + Write-Host "DLL built successfully:" + Write-Host " Name : $($item.Name)" + Write-Host " Size : $([math]::Round($item.Length / 1KB, 1)) KB" + Write-Host " Modified: $($item.LastWriteTime)" +} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..9425c95 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,170 @@ +--- +name: Build + +on: + push: + branches: + - main + - develop + tags: + - 'v*' + pull_request: + branches: + - main + - develop + +jobs: + build: + name: Build DLL (windows-2022) + runs-on: windows-2022 + + steps: + - uses: actions/checkout@v6 + + - uses: dtolnay/rust-toolchain@stable + with: + targets: x86_64-pc-windows-msvc + + # ----------------------------------------------------------------------- + # Cache: Rust registry + build artefacts + # ----------------------------------------------------------------------- + - name: Cache Rust build artefacts + uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + target + key: ${{ runner.os }}-cargo-${{ hashFiles('Cargo.lock') }} + restore-keys: ${{ runner.os }}-cargo- + + # ----------------------------------------------------------------------- + # Cache: vcpkg installed packages (keyed on vcpkg.json) + # ----------------------------------------------------------------------- + - name: Cache vcpkg packages + uses: actions/cache@v4 + with: + path: vcpkg_installed + key: vcpkg-x64-windows-static-${{ hashFiles('vcpkg.json') }} + restore-keys: vcpkg-x64-windows-static- + + # ----------------------------------------------------------------------- + # OpenSSL via vcpkg manifest mode (triplet x64-windows-static) + # Overrides the hardcoded local path in .cargo/config.toml [env]. + # ----------------------------------------------------------------------- + - name: Install OpenSSL via vcpkg + shell: pwsh + run: | + $ErrorActionPreference = "Stop" + $vcpkgRoot = if ($env:VCPKG_INSTALLATION_ROOT) { $env:VCPKG_INSTALLATION_ROOT } ` + elseif ($env:VCPKG_ROOT) { $env:VCPKG_ROOT } ` + else { "C:\vcpkg" } + Write-Host "vcpkg root: $vcpkgRoot" + & "$vcpkgRoot\vcpkg.exe" install --triplet x64-windows-static + $opensslDir = Join-Path (Get-Location) "vcpkg_installed\x64-windows-static" + Write-Host "OPENSSL_DIR=$opensslDir" + echo "OPENSSL_DIR=$opensslDir" >> $env:GITHUB_ENV + echo "OPENSSL_STATIC=1" >> $env:GITHUB_ENV + + # ----------------------------------------------------------------------- + # LIBCLANG_PATH — required by build.rs (bindgen 0.71 to parse sqlcrypt.h) + # windows-2022 runners ship LLVM pre-installed at C:\Program Files\LLVM. + # Falls back to the VS-bundled clang, then installs via Chocolatey. + # ----------------------------------------------------------------------- + - name: Set LIBCLANG_PATH for bindgen + shell: pwsh + run: | + $ErrorActionPreference = "Stop" + $candidates = @( + "C:\Program Files\LLVM\bin", + "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\Llvm\x64\bin", + "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\Llvm\x64\bin", + "C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\Llvm\x64\bin" + ) + $llvmBin = $null + foreach ($c in $candidates) { + if (Test-Path "$c\libclang.dll") { $llvmBin = $c; break } + } + if (-not $llvmBin) { + Write-Host "libclang.dll not found in standard locations; installing LLVM via Chocolatey..." + choco install llvm -y --no-progress + $llvmBin = "C:\Program Files\LLVM\bin" + } + Write-Host "LIBCLANG_PATH=$llvmBin" + echo "LIBCLANG_PATH=$llvmBin" >> $env:GITHUB_ENV + + # ----------------------------------------------------------------------- + # Build + # ----------------------------------------------------------------------- + - name: Build DLL + shell: pwsh + run: | + $ErrorActionPreference = "Stop" + . .\.github\scripts\build_ekm_dll.ps1 + Build-EkmDll + + # ----------------------------------------------------------------------- + # Upload: DLL + PowerShell scripts (for operator signing + deployment) + # ----------------------------------------------------------------------- + - name: Upload artefacts + uses: actions/upload-artifact@v7 + with: + name: cosmian-ekm-sql-server + path: | + target/release/cosmian_ekm_sql_server.dll + scripts/ + retention-days: 1 + if-no-files-found: error + + # --------------------------------------------------------------------------- + # Publish to package.cosmian.com — skipped on pull requests + # Uses the same self-hosted runner + Docker container pattern as the kms repo. + # Requires /home/cosmian/.ssh/id_rsa to be present on the self-hosted runner. + # --------------------------------------------------------------------------- + publish: + name: Publish to package.cosmian.com + needs: build + if: github.event_name != 'pull_request' + runs-on: [self-hosted, not-sgx] + container: + image: cosmian/docker_doc_ci + volumes: + - /home/cosmian/.ssh/id_rsa:/root/.ssh/id_rsa + + steps: + - name: Download artefacts + uses: actions/download-artifact@v8 + with: + name: cosmian-ekm-sql-server + path: . + + - name: List downloaded files + run: | + set -ex + find . -type f -print + + - name: Push to package.cosmian.com + shell: bash + run: | + set -ex + if [[ "${GITHUB_REF}" =~ refs/tags/(.+) ]]; then + BRANCH="${BASH_REMATCH[1]}" + else + HEAD_REF="${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" + BRANCH="last_build/${HEAD_REF}" + fi + + DEST_DIR="/mnt/package/ekm_sql_server/${BRANCH}/windows/x86_64" + ssh -o 'StrictHostKeyChecking no' -i /root/.ssh/id_rsa \ + cosmian@package.cosmian.com mkdir -p "${DEST_DIR}/scripts" + + # Upload DLL + DLL=$(find . -name 'cosmian_ekm_sql_server.dll' -print -quit) + scp -o 'StrictHostKeyChecking no' -i /root/.ssh/id_rsa \ + "${DLL}" cosmian@package.cosmian.com:"${DEST_DIR}/" + + # Upload PowerShell operator scripts (sign + deploy) + while IFS= read -r -d '' ps1; do + scp -o 'StrictHostKeyChecking no' -i /root/.ssh/id_rsa \ + "${ps1}" cosmian@package.cosmian.com:"${DEST_DIR}/scripts/" + done < <(find . -name '*.ps1' -print0) diff --git a/.gitignore b/.gitignore index ea8c4bf..d3c9606 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /target +.cargo_check diff --git a/Cargo.lock b/Cargo.lock index 5deb6ac..603d717 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1966,9 +1966,9 @@ dependencies = [ [[package]] name = "rustc-hash" -version = "2.1.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" +checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" [[package]] name = "rustc_version" diff --git a/build.rs b/build.rs index ec5d6d3..8579f91 100644 --- a/build.rs +++ b/build.rs @@ -14,6 +14,20 @@ fn main() { .clang_arg("-Wno-macro-redefined") // We implement the exported functions ourselves; only generate types .blocklist_function(".*") + // bindgen opaque-izes _GUID in C++ mode; provide the correct definition manually + .blocklist_type("_GUID") + .blocklist_type("GUID") + .raw_line( + "#[repr(C)]\n\ + #[derive(Debug, Default, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]\n\ + pub struct _GUID {\n\ + \x20 pub Data1: u32,\n\ + \x20 pub Data2: u16,\n\ + \x20 pub Data3: u16,\n\ + \x20 pub Data4: [u8; 8usize],\n\ + }\n\ + pub type GUID = _GUID;", + ) // Generate Rust enums for ergonomic use .rustified_enum(".*") .derive_debug(true)