Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 65 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,49 @@ on:

jobs:
build-linux:
name: Linux
name: Linux (${{ matrix.openssl }} ${{ matrix.build_type }})
runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
build_type: [Release, Debug]
openssl: [openssl3]
include:
- openssl: openssl1.1
build_type: Release
- openssl: openssl1.1
build_type: Debug

steps:
- uses: actions/checkout@v4

- name: Install dependencies
- name: Install OpenSSL 3.x
if: matrix.openssl == 'openssl3'
run: |
sudo apt-get update
sudo apt-get install -y libssl-dev

- name: Build and install OpenSSL 1.1
if: matrix.openssl == 'openssl1.1'
run: |
sudo apt-get update
sudo apt-get install -y build-essential
curl -fsSL https://www.openssl.org/source/openssl-1.1.1w.tar.gz | tar xz
cd openssl-1.1.1w
./config --prefix=/opt/openssl-1.1 --openssldir=/opt/openssl-1.1 no-shared
make -j$(nproc)
sudo make install_sw
cd ..
rm -rf openssl-1.1.1w

- name: Configure CMake
run: |
cmake -B build \
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \
-DOPENSSL_ROOT_DIR="$(brew --prefix openssl@3)" \
-DPRIVACY_PASS_BUILD_TESTS=ON \
-DPRIVACY_PASS_BUILD_BENCHMARKS=ON \
-DPRIVACY_PASS_BUILD_MOQ=ON
-DPRIVACY_PASS_BUILD_MOQ=ON \
${{ matrix.openssl == 'openssl1.1' && '-DOPENSSL_ROOT_DIR=/opt/openssl-1.1' || '' }}

- name: Build
run: cmake --build build --parallel
Expand Down Expand Up @@ -96,6 +116,47 @@ jobs:
- name: Test
run: ctest --test-dir build --output-on-failure -C ${{ matrix.build_type }}

build-boringssl:
name: Linux (BoringSSL ${{ matrix.build_type }})
runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
build_type: [Release, Debug]

steps:
- uses: actions/checkout@v4

- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y build-essential ninja-build

- name: Clone and build BoringSSL
run: |
git clone --depth 1 https://boringssl.googlesource.com/boringssl /tmp/boringssl
cmake -B /tmp/boringssl/build -S /tmp/boringssl -GNinja -DCMAKE_BUILD_TYPE=Release
cmake --build /tmp/boringssl/build --target crypto ssl

- name: Configure CMake
run: |
cmake -B build \
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \
-DPRIVACY_PASS_CRYPTO_BACKEND=boringssl \
-DOPENSSL_ROOT_DIR=/tmp/boringssl \
-DOPENSSL_INCLUDE_DIR=/tmp/boringssl/include \
-DOPENSSL_CRYPTO_LIBRARY=/tmp/boringssl/build/libcrypto.a \
-DOPENSSL_SSL_LIBRARY=/tmp/boringssl/build/libssl.a \
-DPRIVACY_PASS_BUILD_TESTS=ON \
-DPRIVACY_PASS_BUILD_BENCHMARKS=ON \
-DPRIVACY_PASS_BUILD_MOQ=ON

- name: Build
run: cmake --build build --parallel

- name: Test
run: ctest --test-dir build --output-on-failure

sanitizers:
runs-on: ubuntu-24.04
steps:
Expand Down
55 changes: 48 additions & 7 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ option(PRIVACY_PASS_BUILD_MOQ "Build MOQ extension" ON)
option(PRIVACY_PASS_BUILD_EXAMPLES "Build examples" ON)
option(PRIVACY_PASS_ENABLE_SANITIZERS "Enable address and undefined sanitizers" OFF)

# Crypto backend selection: "auto", "openssl", or "boringssl"
set(PRIVACY_PASS_CRYPTO_BACKEND "auto" CACHE STRING "Crypto backend: auto, openssl, or boringssl")

# Sanitizer flags (applied globally since they affect linking)
if(PRIVACY_PASS_ENABLE_SANITIZERS)
add_compile_options(-fsanitize=address,undefined -fno-omit-frame-pointer)
Expand All @@ -29,9 +32,35 @@ function(privacy_pass_set_warnings target)
endfunction()

# Dependencies
find_package(OpenSSL 3.0 REQUIRED)

include(FetchContent)
include(CheckIncludeFileCXX)

# Find OpenSSL (works for both OpenSSL and BoringSSL)
if(PRIVACY_PASS_CRYPTO_BACKEND STREQUAL "auto" OR PRIVACY_PASS_CRYPTO_BACKEND STREQUAL "openssl")
find_package(OpenSSL 3.0 QUIET)
if(NOT OPENSSL_FOUND)
find_package(OpenSSL REQUIRED)
endif()
else()
find_package(OpenSSL REQUIRED)
endif()

# Detect BoringSSL via header
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
check_include_file_cxx("openssl/is_boringssl.h" HAVE_BORINGSSL)

# Resolve the crypto backend
if(PRIVACY_PASS_CRYPTO_BACKEND STREQUAL "boringssl" OR
(PRIVACY_PASS_CRYPTO_BACKEND STREQUAL "auto" AND HAVE_BORINGSSL))
set(CRYPTO_BACKEND "boringssl")
elseif(PRIVACY_PASS_CRYPTO_BACKEND STREQUAL "openssl" OR
PRIVACY_PASS_CRYPTO_BACKEND STREQUAL "auto")
set(CRYPTO_BACKEND "openssl")
else()
message(FATAL_ERROR "Unknown crypto backend: ${PRIVACY_PASS_CRYPTO_BACKEND}")
endif()

message(STATUS "Privacy Pass crypto backend: ${CRYPTO_BACKEND}")

# Silence MSVC deprecation warnings for spdlog's bundled fmt library
if(MSVC)
Expand All @@ -51,7 +80,6 @@ FetchContent_MakeAvailable(spdlog)

# Fetch doctest if building tests
if(PRIVACY_PASS_BUILD_TESTS)
include(FetchContent)
FetchContent_Declare(
doctest
GIT_REPOSITORY https://github.com/doctest/doctest.git
Expand All @@ -70,7 +98,6 @@ endif()

# Fetch Google Benchmark if building benchmarks
if(PRIVACY_PASS_BUILD_BENCHMARKS)
include(FetchContent)
FetchContent_Declare(
benchmark
GIT_REPOSITORY https://github.com/google/benchmark.git
Expand Down Expand Up @@ -105,12 +132,13 @@ target_link_libraries(privacy_pass_core PRIVATE
spdlog::spdlog
)

# Crypto library
# Crypto library — single source files, backend selected via compat.hpp
add_library(privacy_pass_crypto
src/crypto/blind_rsa.cpp
src/crypto/voprf.cpp
src/crypto/hash.cpp
src/crypto/random.cpp
src/crypto/blind_rsa.cpp
src/crypto/voprf.cpp
src/crypto/init.cpp
)
privacy_pass_set_warnings(privacy_pass_crypto)

Expand All @@ -119,6 +147,13 @@ target_link_libraries(privacy_pass_crypto PUBLIC
)
target_link_libraries(privacy_pass_crypto PRIVATE spdlog::spdlog)

# Backend compile definition so code can query which backend is active
if(CRYPTO_BACKEND STREQUAL "boringssl")
target_compile_definitions(privacy_pass_crypto PUBLIC PRIVACY_PASS_WITH_BORINGSSL)
else()
target_compile_definitions(privacy_pass_crypto PUBLIC PRIVACY_PASS_WITH_OPENSSL)
endif()

# HTTP layer
add_library(privacy_pass_http
src/http/auth_scheme.cpp
Expand Down Expand Up @@ -241,6 +276,7 @@ if(PRIVACY_PASS_BUILD_TESTS)
tests/test_origin.cpp
tests/test_integration.cpp
tests/test_http.cpp
tests/test_crypto_provider.cpp
)
if(PRIVACY_PASS_BUILD_MOQ)
list(APPEND TEST_SOURCES tests/test_moq.cpp)
Expand All @@ -254,6 +290,10 @@ if(PRIVACY_PASS_BUILD_TESTS)
doctest::doctest
nlohmann_json::nlohmann_json
)
# Treat third-party headers as system includes to suppress warnings on MSVC
target_include_directories(privacy_pass_tests SYSTEM PRIVATE
${doctest_SOURCE_DIR}/doctest
)
target_compile_definitions(privacy_pass_tests PRIVATE
PRIVACY_PASS_TEST_DATA_DIR="${CMAKE_CURRENT_SOURCE_DIR}/tests/test_data"
)
Expand All @@ -271,6 +311,7 @@ if(PRIVACY_PASS_BUILD_BENCHMARKS)
benchmarks/bench_crypto.cpp
benchmarks/bench_token_issuance.cpp
benchmarks/bench_serialization.cpp
benchmarks/bench_crypto_provider.cpp
)
privacy_pass_set_warnings(privacy_pass_benchmarks)

Expand Down
19 changes: 15 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ C++ implementation of the Privacy Pass protocol ([RFC9576](https://datatracker.i
- Token challenges, requests, responses, and redemption
- Optional MOQ extension ([draft-ietf-moq-privacy-pass-auth-02](https://datatracker.ietf.org/doc/html/draft-ietf-moq-privacy-pass-auth-02))
- Modern C++23 with `std::expected` error handling
- Pluggable crypto backend: OpenSSL 3.x or BoringSSL ([details](docs/crypto_backend.md))

## Building

Requires CMake 3.20+, C++23 compiler, and OpenSSL 3.x.
Requires CMake 3.20+, C++23 compiler, and OpenSSL (1.1 or 3.x) or BoringSSL.
See [docs/crypto_backend.md](docs/crypto_backend.md) for multi-backend setup.

```bash
cmake -B build
Expand All @@ -38,9 +40,18 @@ just moq=OFF build # Build without MOQ extension
## Testing

```bash
just test
# or
./build/privacy_pass_tests
just test # Test with system OpenSSL
just test-openssl3 # Test with OpenSSL 3.x
just test-openssl11 # Test with OpenSSL 1.1
just test-boringssl # Test with BoringSSL
just test-all-crypto # Test all three variants
```

Custom OpenSSL paths:

```bash
just test-openssl11 dir=/path/to/openssl-1.1
just test-openssl3 dir=/path/to/openssl-3.0
```

## License
Expand Down
Loading
Loading