Skip to content

Commit

Permalink
Fix ngtcp2 upstream problem (#214)
Browse files Browse the repository at this point in the history
* stricter layering for cache optimization in OpenSSL3

* add github dockerx build for a first demo

* add explicit group selection in OpenSSL3

* fixing ngtcp2 paths
  • Loading branch information
baentsch committed Jul 12, 2023
1 parent a529d83 commit aa98e3b
Show file tree
Hide file tree
Showing 7 changed files with 203 additions and 62 deletions.
6 changes: 3 additions & 3 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ jobs:
- run:
name: Spot-test Provider -- One baseline and one hybrid QSC alg
command: |
docker run --rm --name oqs-ossl3 oqs-ossl3-img sh -c "/opt/oqssa/bin/serverstart.sh; sleep 2; echo 'GET /' | openssl s_client -connect localhost --groups kyber512 --CAfile /opt/oqssa/bin/CA.crt" &&
docker run --rm --name oqs-ossl3 oqs-ossl3-img sh -c "KEM_ALG=p521_frodo1344aes /opt/oqssa/bin/serverstart.sh; sleep 2; echo 'GET /' | openssl s_client -connect localhost --groups p521_frodo1344aes --CAfile /opt/oqssa/bin/CA.crt"
docker run --rm --name oqs-ossl3 oqs-ossl3-img sh -c "openssl list -providers; /opt/openssl32/bin/serverstart.sh; sleep 2; echo 'GET /' | openssl s_client -connect localhost --groups kyber768 --CAfile /opt/openssl32/bin/CA.crt" &&
docker run --rm --name oqs-ossl3 oqs-ossl3-img sh -c "KEM_ALG=p521_frodo1344aes /opt/openssl32/bin/serverstart.sh; sleep 2; echo 'GET /' | openssl s_client -connect localhost --groups p521_frodo1344aes --CAfile /opt/openssl32/bin/CA.crt"
- when:
condition:
or:
Expand Down Expand Up @@ -418,7 +418,7 @@ jobs:
command: |
docker network create ngtcp2-test
docker run --network ngtcp2-test --name oqs-ngtcp2server oqs-ngtcp2-server &
docker run --network ngtcp2-test -it --name oqs-ngtcp2client oqs-ngtcp2-client sh -c 'client --exit-on-first-stream-close --groups kyber512 oqs-ngtcp2server 6000'
docker run --network ngtcp2-test -it --name oqs-ngtcp2client oqs-ngtcp2-client sh -c 'qtlsclient --exit-on-first-stream-close --groups kyber512 oqs-ngtcp2server 6000'
docker logs oqs-ngtcp2client | grep "QUIC handshake has been confirmed"
docker rm oqs-ngtcp2client
docker stop oqs-ngtcp2server
Expand Down
112 changes: 112 additions & 0 deletions .github/workflows/linux.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
name:

on:
push:
branches: [ '*' ]
pull_request:
branches: [ "main" ]
repository_dispatch:
types: [ '*' ]

env:
REGISTRY_IMAGE: openquantumsafe/openssl3

jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
platform:
- linux/amd64
# - linux/arm/v6
# - linux/arm/v7
# - linux/arm64
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Docker meta
id: meta
uses: docker/metadata-action@v4
with:
images: ${{ env.REGISTRY_IMAGE }}
-
name: Set up QEMU
uses: docker/setup-qemu-action@v2
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Build and push OpenSSL3+oqs-provider by digest
id: build
uses: docker/build-push-action@v4
with:
context: openssl3
platforms: ${{ matrix.platform }}
labels: ${{ steps.meta.outputs.labels }}
outputs: type=image,name=${{ env.REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true
cache-from: type=gha
cache-to: type=gha,mode=max
# cache-from: type=registry,ref=${{ env.REGISTRY_IMAGE }}:buildcache
# cache-to: type=registry,ref=${{ env.REGISTRY_IMAGE }}:buildcache,mode=max
-
name: Export digest
run: |
mkdir -p /tmp/digests
digest="${{ steps.build.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}"
-
name: Upload digest
uses: actions/upload-artifact@v3
with:
name: digests
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1

merge:
runs-on: ubuntu-latest
needs:
- build
if: github.ref == 'refs/heads/main'
steps:
-
name: Download digests
uses: actions/download-artifact@v3
with:
name: digests
path: /tmp/digests
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Docker meta
id: meta
uses: docker/metadata-action@v4
with:
images: ${{ env.REGISTRY_IMAGE }}
-
name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Create manifest list and push
working-directory: /tmp/digests
run: |
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf '${{ env.REGISTRY_IMAGE }}@sha256:%s ' *)
-
name: Inspect image
run: |
docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ steps.meta.outputs.version }}
6 changes: 3 additions & 3 deletions ngtcp2/Dockerfile-client
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ RUN mkdir /opt/lib && cd /opt/lib && \
cp /opt/ngtcp2/lib/.libs/libngtcp2.so.* . && \
cp /usr/lib/libev.so.* . && \
cp /opt/nghttp3/build/lib/libnghttp3.so.* . && \
cp /opt/ngtcp2/crypto/openssl/.libs/libngtcp2_crypto_openssl.so.* . && \
cp /opt/ngtcp2/crypto/quictls/.libs/libngtcp2_crypto_quictls.so.* . && \
cp /opt/oqssa/lib64/libssl.so.* . && \
cp /opt/oqssa/lib64/libcrypto.so.* . && \
cp /usr/lib/libstdc++.so.* . && \
Expand All @@ -63,9 +63,9 @@ ENV DEBIAN_FRONTEND=noninteractive
RUN apk update && apk upgrade

# copy executable
COPY --from=intermediate /opt/ngtcp2/examples/client /usr/local/bin
COPY --from=intermediate /opt/ngtcp2/examples/qtlsclient /usr/local/bin

# copy shared object dependencies and configuration file
COPY --from=intermediate /opt/lib /usr/local/lib
COPY --from=intermediate /opt/oqssa/lib64/ossl-modules/oqsprovider.so /opt/oqssa/lib64/ossl-modules/oqsprovider.so
COPY --from=intermediate /opt/oqssa/ssl/openssl.cnf /opt/oqssa/ssl/openssl.cnf
COPY --from=intermediate /opt/oqssa/ssl/openssl.cnf /opt/oqssa/ssl/openssl.cnf
6 changes: 3 additions & 3 deletions ngtcp2/Dockerfile-server
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ RUN mkdir /opt/lib && cd /opt/lib && \
cp /opt/ngtcp2/lib/.libs/libngtcp2.so.* . && \
cp /usr/lib/libev.so.* . && \
cp /opt/nghttp3/build/lib/libnghttp3.so.* . && \
cp /opt/ngtcp2/crypto/openssl/.libs/libngtcp2_crypto_openssl.so.* . && \
cp /opt/ngtcp2/crypto/quictls/.libs/libngtcp2_crypto_quictls.so.* . && \
cp /opt/oqssa/lib64/libssl.so.* . && \
cp /opt/oqssa/lib64/libcrypto.so.* . && \
cp /usr/lib/libstdc++.so.* . && \
Expand All @@ -68,7 +68,7 @@ RUN apk update && apk upgrade && apk add mailcap && echo "This is my index page"
COPY ./serverstart.sh .

# copy executable
COPY --from=intermediate /opt/ngtcp2/examples/server /usr/local/bin
COPY --from=intermediate /opt/ngtcp2/examples/qtlsserver /usr/local/bin

# Copy server key and self-signed certificate files
COPY --from=intermediate /certs /certs
Expand All @@ -78,4 +78,4 @@ COPY --from=intermediate /opt/lib /usr/local/lib
COPY --from=intermediate /opt/oqssa/lib64/ossl-modules/oqsprovider.so /opt/oqssa/lib64/ossl-modules/oqsprovider.so
COPY --from=intermediate /opt/oqssa/ssl/openssl.cnf /opt/oqssa/ssl/openssl.cnf

CMD ["./serverstart.sh"]
CMD ["./serverstart.sh"]
2 changes: 1 addition & 1 deletion ngtcp2/serverstart.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ if [ "x$KEM_ALG" == "x" ]; then
fi

# Start ngtcp2 server accepting only the specified KEM_ALG
server --groups $KEM_ALG "*" 6000 /certs/server.key /certs/server.crt
qtlsserver --groups $KEM_ALG "*" 6000 /certs/server.key /certs/server.crt
127 changes: 78 additions & 49 deletions openssl3/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,105 +1,134 @@
# Multi-stage build: First the full builder image:

# Default location where all binaries wind up:
ARG INSTALLDIR=/opt/oqssa
ARG INSTALLDIR_OPENSSL=/opt/openssl32
ARG INSTALLDIR_LIBOQS=/opt/liboqs

# liboqs build type variant; maximum portability of image:
ARG LIBOQS_BUILD_DEFINES="-DOQS_DIST_BUILD=ON"

# Define the degree of parallelism when building the image; leave the number away only if you know what you are doing
ARG MAKE_DEFINES="-j 2"
ARG MAKE_DEFINES="-j 8"

# Change this at your own risk: OSSL3 can handle OQS-sigs only
# after https://github.com/openssl/openssl/pull/19312 lands
ARG SIG_ALG="rsa:2048"
ARG SIG_ALG="dilithium3"

FROM alpine:3.13 as intermediate
FROM alpine:3.13 as buildopenssl
# Take in all global args
ARG CURL_VERSION
ARG INSTALLDIR
ARG INSTALLDIR_OPENSSL
ARG INSTALLDIR_LIBOQS
ARG LIBOQS_BUILD_DEFINES
ARG MAKE_DEFINES
ARG SIG_ALG

LABEL version="1"

ENV DEBIAN_FRONTEND noninteractive

RUN apk update && apk upgrade

# Get all software packages required for builing all components:
# Get all software packages required for builing openssl
RUN apk add build-base linux-headers \
libtool automake autoconf \
make \
git wget

# get current openssl sources
RUN mkdir /optbuild && cd /optbuild && git clone --depth 1 --branch master https://github.com/openssl/openssl.git

# build OpenSSL3
WORKDIR /optbuild/openssl
RUN LDFLAGS="-Wl,-rpath -Wl,${INSTALLDIR_OPENSSL}/lib64" ./config shared --prefix=${INSTALLDIR_OPENSSL} && \
make ${MAKE_DEFINES} && make install && if [ -d ${INSTALLDIR_OPENSSL}/lib64 ]; then ln -s ${INSTALLDIR_OPENSSL}/lib64 ${INSTALLDIR_OPENSSL}/lib; fi && if [ -d ${INSTALLDIR_OPENSSL}/lib ]; then ln -s ${INSTALLDIR_OPENSSL}/lib ${INSTALLDIR_OPENSSL}/lib64; fi

FROM alpine:3.13 as buildliboqs
# Take in all global args
ARG INSTALLDIR_OPENSSL
ARG INSTALLDIR_LIBOQS
ARG LIBOQS_BUILD_DEFINES
ARG MAKE_DEFINES
ARG SIG_ALG

LABEL version="1"
ENV DEBIAN_FRONTEND noninteractive

# Get all software packages required for builing liboqs:
RUN apk add build-base linux-headers \
libtool automake autoconf cmake ninja \
make \
openssl openssl-dev \
git docker wget
git wget

# get all sources
WORKDIR /opt
RUN git clone --depth 1 --branch main https://github.com/open-quantum-safe/liboqs && \
git clone --depth 1 --branch master https://github.com/openssl/openssl.git && \
git clone --depth 1 --branch main https://github.com/open-quantum-safe/oqs-provider.git
# Get OpenSSL image (from cache)
COPY --from=buildopenssl ${INSTALLDIR_OPENSSL} ${INSTALLDIR_OPENSSL}

WORKDIR /opt/liboqs
RUN mkdir build && cd build && cmake -G"Ninja" .. ${LIBOQS_BUILD_DEFINES} -DCMAKE_INSTALL_PREFIX=${INSTALLDIR} && ninja install
RUN mkdir /optbuild && cd /optbuild && git clone --depth 1 --branch main https://github.com/open-quantum-safe/liboqs

# build OpenSSL3
WORKDIR /opt/openssl
RUN LDFLAGS="-Wl,-rpath -Wl,${INSTALLDIR}/lib64" ./config shared --prefix=${INSTALLDIR} && \
make ${MAKE_DEFINES} && make install;
WORKDIR /optbuild/liboqs
RUN mkdir build && cd build && cmake -G"Ninja" .. -DOPENSSL_ROOT_DIR=${INSTALLDIR_OPENSSL} ${LIBOQS_BUILD_DEFINES} -DCMAKE_INSTALL_PREFIX=${INSTALLDIR_LIBOQS} && ninja install

FROM alpine:3.13 as buildoqsprovider
# Take in all global args
ARG INSTALLDIR_OPENSSL
ARG INSTALLDIR_LIBOQS
ARG LIBOQS_BUILD_DEFINES
ARG MAKE_DEFINES
ARG SIG_ALG

# set path to use 'new' openssl & curl. Dyn libs have been properly linked in to match
ENV PATH="${INSTALLDIR}/bin:${PATH}"
LABEL version="1"
ENV DEBIAN_FRONTEND noninteractive

# Get all software packages required for builing oqsprovider
RUN apk add build-base linux-headers \
libtool cmake ninja \
git wget

RUN mkdir /optbuild && cd /optbuild && git clone --depth 1 --branch main https://github.com/open-quantum-safe/oqs-provider.git

# Get openssl32 and liboqs
COPY --from=buildopenssl ${INSTALLDIR_OPENSSL} ${INSTALLDIR_OPENSSL}
COPY --from=buildliboqs ${INSTALLDIR_LIBOQS} ${INSTALLDIR_LIBOQS}

# build & install provider (and activate by default)
WORKDIR /opt/oqs-provider
RUN ln -s ../openssl . && cmake -DOPENSSL_ROOT_DIR=${INSTALLDIR} -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=${INSTALLDIR} -S . -B _build && cmake --build _build && cp _build/lib/oqsprovider.so ${INSTALLDIR}/lib64/ossl-modules && sed -i "s/default = default_sect/default = default_sect\noqsprovider = oqsprovider_sect/g" /opt/oqssa/ssl/openssl.cnf && sed -i "s/\[default_sect\]/\[default_sect\]\nactivate = 1\n\[oqsprovider_sect\]\nactivate = 1\n/g" /opt/oqssa/ssl/openssl.cnf
WORKDIR /optbuild/oqs-provider
RUN liboqs_DIR=${INSTALLDIR_LIBOQS} cmake -DOPENSSL_ROOT_DIR=${INSTALLDIR_OPENSSL} -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=${INSTALLDIR_OPENSSL} -S . -B _build && cmake --build _build && cmake --install _build && cp _build/lib/oqsprovider.so ${INSTALLDIR_OPENSSL}/lib64/ossl-modules && sed -i "s/default = default_sect/default = default_sect\noqsprovider = oqsprovider_sect/g" ${INSTALLDIR_OPENSSL}/ssl/openssl.cnf && sed -i "s/\[default_sect\]/\[default_sect\]\nactivate = 1\n\[oqsprovider_sect\]\nactivate = 1\n/g" ${INSTALLDIR_OPENSSL}/ssl/openssl.cnf && sed -i "s/providers = provider_sect/providers = provider_sect\nssl_conf = ssl_sect\n\n\[ssl_sect\]\nsystem_default = system_default_sect\n\n\[system_default_sect\]\nGroups = \$ENV\:\:DEFAULT_GROUPS\n/g" ${INSTALLDIR_OPENSSL}/ssl/openssl.cnf && sed -i "s/HOME\t\t\t= ./HOME = .\nDEFAULT_GROUPS = kyber768/g" ${INSTALLDIR_OPENSSL}/ssl/openssl.cnf

# generate certificates for openssl s_server, which is what we will test curl against
ENV OPENSSL=${INSTALLDIR}/bin/openssl
ENV OPENSSL_CNF=${INSTALLDIR}/ssl/openssl.cnf
WORKDIR ${INSTALLDIR_OPENSSL}/bin
# set path to use 'new' openssl. Dyn libs have been properly linked in to match
ENV PATH="${INSTALLDIR_OPENSSL}/bin:${PATH}"

WORKDIR ${INSTALLDIR}/bin
# generate CA key and cert
RUN set -x; \
${OPENSSL} req -x509 -new -newkey ${SIG_ALG} -keyout CA.key -out CA.crt -nodes -subj "/CN=oqstest CA" -days 365 -config ${OPENSSL_CNF}
openssl req -x509 -new -newkey ${SIG_ALG} -keyout CA.key -out CA.crt -nodes -subj "/CN=oqstest CA" -days 365

## second stage: Only create minimal image without build tooling and intermediate build results generated above:
FROM alpine:3.13 as dev
# Take in all global args
ARG INSTALLDIR
ARG INSTALLDIR_OPENSSL
ARG SIG_ALG

# Only retain the ${INSTALLDIR} contents in the final image
COPY --from=intermediate ${INSTALLDIR} ${INSTALLDIR}
# Only retain the ${INSTALLDIR_OPENSSL} contents in the final image
COPY --from=buildoqsprovider ${INSTALLDIR_OPENSSL} ${INSTALLDIR_OPENSSL}

# set path to use 'new' openssl. Dyn libs have been properly linked in to match
ENV PATH="${INSTALLDIR}/bin:${PATH}"
ENV PATH="${INSTALLDIR_OPENSSL}/bin:${PATH}"

# generate certificates for openssl s_server, which is what we will test curl against
ENV OPENSSL=${INSTALLDIR}/bin/openssl
ENV OPENSSL_CNF=${INSTALLDIR}/ssl/openssl.cnf

WORKDIR ${INSTALLDIR}/bin
WORKDIR ${INSTALLDIR_OPENSSL}/bin

# oqs-provider cannot deal with OQS sigs, so use classic crypto for sigs
# generate server CSR using pre-set CA.key and cert
# and generate server cert
RUN set -x && mkdir /opt/test; \
${OPENSSL} req -new -newkey ${SIG_ALG} -keyout /opt/test/server.key -out /opt/test/server.csr -nodes -subj "/CN=localhost" -config ${OPENSSL_CNF}; \
${OPENSSL} x509 -req -in /opt/test/server.csr -out /opt/test/server.crt -CA CA.crt -CAkey CA.key -CAcreateserial -days 365;
RUN set -x && mkdir -p /opt/test; \
openssl version && openssl list -providers && openssl req -new -newkey ${SIG_ALG} -keyout /opt/test/server.key -out /opt/test/server.csr -nodes -subj "/CN=localhost" && \
openssl x509 -req -in /opt/test/server.csr -out /opt/test/server.crt -CA CA.crt -CAkey CA.key -CAcreateserial -days 365;

COPY serverstart.sh ${INSTALLDIR}/bin
COPY serverstart.sh ${INSTALLDIR_OPENSSL}/bin

WORKDIR ${INSTALLDIR}
WORKDIR ${INSTALLDIR_OPENSSL}

FROM dev
ARG INSTALLDIR
ARG INSTALLDIR_OPENSSL

WORKDIR /

# Enable a normal user to create new server keys off set CA
RUN addgroup -g 1000 -S oqs && adduser --uid 1000 -S oqs -G oqs && chown -R oqs.oqs /opt/test && chmod go+r ${INSTALLDIR}/bin/CA.key
RUN addgroup -g 1000 -S oqs && adduser --uid 1000 -S oqs -G oqs && chown -R oqs.oqs /opt/test && chmod go+r ${INSTALLDIR_OPENSSL}/bin/CA.key

#USER oqs
CMD ["serverstart.sh"]
Expand Down
6 changes: 3 additions & 3 deletions openssl3/serverstart.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ set -e

# Optionally set KEM to one defined in https://github.com/open-quantum-safe/openssl#key-exchange
if [ "x$KEM_ALG" == "x" ]; then
export KEM_ALG=kyber512
export KEM_ALG=kyber768
fi

# OQS sig certs not yet supported in OSSL3 oqsprovider

# Start a TLS1.3 test server based on OpenSSL accepting only the specified KEM_ALG
openssl s_server -cert /opt/test/server.crt -key /opt/test/server.key -groups $KEM_ALG -www -tls1_3 -accept localhost:4433&

echo "Test server started for KEM $KEM_ALG at port 4433"

# Open a shell for local experimentation
sh

0 comments on commit aa98e3b

Please sign in to comment.