quiche icon indicating copy to clipboard operation
quiche copied to clipboard

Add support for OpenSSL as a TLS backend

Open andrewkdinh opened this issue 8 months ago • 7 comments

This PR adds support for the canonical OpenSSL as a TLS backend in quiche. It can be enabled by compiling with --no-default-features --features openssl.

Design Notes

This implementation is modeled after PR #1605, which added support for QuicTLS. The logic has been updated to use:

  • openssl feature: enables canonical OpenSSL as the TLS backend
  • quictls feature: enables QuicTLS as the TLS backend

Because OpenSSL’s QUIC API differs significantly from BoringSSL and QuicTLS, additional required data is stored and propogated using ExData. Essentially all the code in this PR is guarded with #[cfg(feature = "openssl")].

Dependency management in Cargo.toml had to be slightly adjusted to allow Quiche to be built with only one TLS backend. Default functionality still matches existing functionality.

CI

To ensure long-term compatibility, I have added a CI job that compiles with the openssl feature enabled.

Limitations

0-RTT Support: Not yet implemented because OpenSSL 3.5 doesn't fully support it.

Compile & Run

After compiling OpenSSL, LD_LIBRARY_PATH and PKG_CONFIG_PATH must be set accordingly. For example, if OpenSSL has been compiled to /quiche/openssl-binary, the server and client can be tested with:

$ export LD_LIBRARY_PATH=/quiche/openssl-binary/lib
$ export PKG_CONFIG_PATH=/quiche/openssl-binary/lib/pkgconfig
$ cargo run --no-default-features --features openssl --bin quiche-client -- https://cloudflare-quic.com
$ cargo run --no-default-features --features openssl --bin quiche-server

Tests

Most of the unit tests currently pass with cargo test --no-default-features --features openssl --workspace --exclude tokio-quiche

The current implementation passes all relevant QUIC interop tests.

Confirmed passing interop tests for server and client: handshake,transfer,longrtt,multiplexing,retry,resumption,http3,blackhole,amplificationlimit,transferloss,handshakecorruption,transfercorruption,ipv6

new Dockerfile that uses openssl feature and passes QUIC interop runner tests
FROM rust:1.82 AS build

WORKDIR /build

COPY Cargo.toml ./
COPY apps/ ./apps/
COPY buffer-pool ./buffer-pool/
COPY datagram-socket/ ./datagram-socket/
COPY h3i/ ./h3i/
COPY octets/ ./octets/
COPY qlog/ ./qlog/
COPY quiche/ ./quiche/
COPY task-killswitch ./task-killswitch/
COPY tokio-quiche ./tokio-quiche/

RUN apt-get update && apt-get install -y cmake && rm -rf /var/lib/apt/lists/*

# Currently uses andrewkdinh/openssl because some extra changes were required to get quiche 
# working. I will merge the required changes to openssl/openssl when everything is ready
RUN apt-get install -y git cmake curl pkg-config && \
    git clone --branch quiche --depth 1 https://github.com/andrewkdinh/openssl.git && \
    cd openssl && \
    ./config no-docs --prefix=/quiche/openssl-binary && \
    make -j $(nproc) && \
    make -j $(nproc) install && \
    rm -rf openssl

ENV LD_LIBRARY_PATH=/quiche/openssl-binary/lib
ENV PKG_CONFIG_PATH=/quiche/openssl-binary/lib/pkgconfig

RUN cargo build --release --manifest-path apps/Cargo.toml --no-default-features --features openssl

##
## quiche-base: quiche image for apps
##
FROM debian:latest AS quiche-base

RUN apt-get update && apt-get install -y ca-certificates && \
    rm -rf /var/lib/apt/lists/*

COPY --from=build \
     /build/target/release/quiche-client \
     /build/target/release/quiche-server \
     /usr/local/bin/

COPY --from=build \
     /quiche/openssl-binary \
     ./openssl-binary/

ENV LD_LIBRARY_PATH=/quiche/openssl-binary/lib
ENV PKG_CONFIG_PATH=/quiche/openssl-binary/lib/pkgconfig

ENV PATH="/usr/local/bin/:${PATH}"
ENV RUST_LOG=info

##
## quiche-qns: quiche image for quic-interop-runner
## https://github.com/marten-seemann/quic-network-simulator
## https://github.com/marten-seemann/quic-interop-runner
##
FROM martenseemann/quic-network-simulator-endpoint:latest AS quiche-qns

WORKDIR /quiche

RUN apt-get update && apt-get install -y wait-for-it && rm -rf /var/lib/apt/lists/*

COPY --from=build \
     /build/target/release/quiche-client \
     /build/target/release/quiche-server \
     /build/apps/run_endpoint.sh \
     ./

COPY --from=build \
     /quiche/openssl-binary \
     ./openssl-binary/

ENV LD_LIBRARY_PATH=/quiche/openssl-binary/lib
ENV PKG_CONFIG_PATH=/quiche/openssl-binary/lib/pkgconfig

ENV RUST_LOG=trace

ENTRYPOINT [ "./run_endpoint.sh" ]

Fixes https://github.com/openssl/project/issues/1146

andrewkdinh avatar May 09 '25 01:05 andrewkdinh

QuicTLS was archived recently. Is it relevant to use this implementation? It looks like a new implementation is https://github.com/quictls/quictls, but currently release workflow is not clear.

pkropachev avatar May 12 '25 15:05 pkropachev

@pkropachev Because quictls/openssl is archived, I think quiche should remove any sort of support for it. Plus, as far as I can tell, quiche built with quictls/openssl doesn't even work in it's current implementation. I can remove support for quictls/openssl in this PR. Perhaps quictls/quictls can be supported in the future, but that is not the aim of this PR.

andrewkdinh avatar May 12 '25 16:05 andrewkdinh

@andrewkdinh thank you for the PR.

Can you help me understand what use case you are tying to fill here and why boringSSL doesn't work for you? Another TLS backend means more code that we need to maintain and also adds to the complexity.

Plus, as far as I can tell, quiche built with quictls/openssl doesn't even work in it's current implementation.

I am not familiar with the history of why quictls was added but it seems like we do have some tests in CI.

toidiu avatar May 15 '25 18:05 toidiu

@toidiu I am an engineer from OpenSSL Corporation, and we're working to ensure robust support for OpenSSL’s third-party QUIC API's across major QUIC implementations. This work builds on our efforts to validate compatibility with widely used QUIC stacks - such as ngtcp2 and msquic - and helps expand the reach of OpenSSL’s QUIC support.

Adding OpenSSL support to Quiche offers greater flexibility for applications seeking to use it as their TLS backend, and aligns with the precedent set when support for QuicTLS was added in PR #1605

In addition, from BoringSSL's README: "Although BoringSSL is an open source project, it is not intended for general use, as OpenSSL is. We don't recommend that third parties depend upon it. Doing so is likely to be frustrating because there are no guarantees of API or ABI stability"

andrewkdinh avatar May 16 '25 06:05 andrewkdinh

why boringSSL doesn't work for you?

A 4-year-old version of the BoringSSL is currently in use. If to be honest this is quite old. See #1761.

pkropachev avatar May 16 '25 10:05 pkropachev

@toidiu any thoughts on supporting openssl?

andrewkdinh avatar Jun 02 '25 15:06 andrewkdinh

@toidiu Ping for any further thoughts on this

andrewkdinh avatar Jul 22 '25 09:07 andrewkdinh