diff --git a/nginx/fulltest-provider/README.md b/nginx/fulltest-provider/README.md deleted file mode 100644 index 7f49b225..00000000 --- a/nginx/fulltest-provider/README.md +++ /dev/null @@ -1,43 +0,0 @@ -# Scripts to generate OQS test server - -This folder contains all scripts to [build a QSC-enabled nginx server running on ubuntu](build-ubuntu.sh) as well as generating all configuration files for running an interoperability test server: Running [python3 genconfig.py](genconfig.py) generates a local/self-signed root CA, all QSC certificates signed by this root CA for the currently supported list of QSC algorithms and the required nginx-server configuration file for a server running at the configured TESTFQDN server address. - -*Note*: These scripts assume -- coherent definition of test server FQDN as TESTFQDN in `genconfig.py` and `ext-csr.conf` files: By default "test.openquantumsafe.org" is set. -- presence of oqs-openssl common definitions file `common.py` (as stored at https://raw.githubusercontent.com/open-quantum-safe/oqs-provider/main/scripts/common.py). -- presence of Docker on the build machine to run the build process, the guest OS needs to be able to mount host directories for Docker (i.e. on Linux, SELinux permissions might be needed). -- presence on the target deploy server (i.e., at the machine designated at TESTFQDN) of a properly deployed [LetsEncrypt server certificate](https://letsencrypt.org/getting-started). - -By default, the server is built to a specific set of versions of `liboqs`, `openssl`, `oqs-provider` and `nginx`. These versions are encoded in `build-ubuntu.sh` and may be changed/upgraded there. - -### HOWTO - -#### Build and deploy test server - -On build machine run - -``` -./build-ubuntu.sh -scp oqs-nginx-{LIBOQS_VERSION}.tgz yourid@yourserver:yourpath -``` - -At 'yourserver' run: -``` -cd / && tar xzvf yourpath/oqs-nginx-{LIBOQS_VERSION}.tgz -cd /opt/nginx -/opt/nginx/sbin/nginx -c interop.conf -``` - -Note that, the oqs-nginx-{LIBOQS_VERSION}.tgz package contains all required configuration files and QSC certificates. **Unpacking the archive may overwrite an existing installation's configuration files. Use with care on a live server.** - -#### Activation - -Execute `OPENSSL_CONF=/opt/openssl/.openssl/ssl/openssl.cnf /opt/nginx/sbin/nginx -c /opt/nginx/interop.conf` to start the test server. - -*Note*: From nginx version 1.25.2, nginx does not try to load OpenSSL configuration if the --with-openssl option was used to built OpenSSL. We therefore have to set the `OPENSSL_CONF` environment variable when activating nginx. - -*Note*: As the server many of ports, the server may need to be configured to permit this, e.g., using `ulimit -S -n 4096`. - -#### Test run - -The `testrun.sh` script runs test connections against all ports configured by the server. To run the script, execute `testrun.sh openquantumsafe/curl`. diff --git a/nginx/fulltest-provider/chromium-template b/nginx/fulltest-provider/chromium-template deleted file mode 100644 index abee3f2a..00000000 --- a/nginx/fulltest-provider/chromium-template +++ /dev/null @@ -1,71 +0,0 @@ - - - - -Open Quantum Safe interop test server for quantum-safe cryptography - Chromium overview - - -

Open Quantum Safe interop test server for quantum-safe cryptography

-

Purpose

- -

This server is an NGINX instance enhanced with support for quantum-safe cryptography (QSC) using software packages provided by the Open Quantum Safe project (OQS).

- -

In order to provide a means for clients to test interoperability with this QSC-enhanced software and the QSC algorithms contained it features separate ports for all QSC signature/key exchange algorithm combinations supported by the current OQS distribution. This page focuses on the algorithms supported by the OQS-enabled Chromium browser build.

- -

Specification details

- -

This nginx server supports

- - -

This corresponds to the OQS release version LIBOQS_RELEASE and oqs-provider version OQSPROVIDER_RELEASE.

- -

These specifications should not be taken as a standard, de facto and otherwise, and are subject to change at any time.

- -

Use the OQS-enabled Chromium build to access this web page. As per the limitations concerning supported algorithms as documented here, only the KEM algorithm combinations listed below will function (P256_BIKEL1, P256_FRODO640AES, P256_KYBER90S512, P256_NTRU_HPS2048509, P256_LIGHTSABER) and no hybrid signature algorithms are supported. - -

More details are available at Github.

- -

An alternative view to all supported algorithms is available at this web page.

- -

Caveats

- -
    -
  1. This test server by no means should be taken as containing production-ready software. See disclaimer. Its purpose is simply to provide a best-effort facility to allow anyone to "test-drive" QSC software packages including testing protocol level interoperability.
  2. - -
- -

Certificates

- -

Each test port provides TLS server authentication using a server certificate generated using the listed QSC-signature algorithm. All server certificates are signed by a common CA certificate using conventional (RSA) cryptography. This certificate is available for download here.

- -

List of all supported QSC Signature / Key Exchange algorithms for use by OQS-enabled Chromium

- -

The list below provides links to the entry points of all OQS signature / key exchange algorithm combinations supported by the OQS-Chromium build.

- - - - - - - - diff --git a/nginx/fulltest-provider/ext-csr.conf b/nginx/fulltest-provider/ext-csr.conf deleted file mode 100644 index b4fc0617..00000000 --- a/nginx/fulltest-provider/ext-csr.conf +++ /dev/null @@ -1,27 +0,0 @@ -[req] -distinguished_name = req_distinguished_name -req_extensions = v3_req -prompt = no - -[req_distinguished_name] -CN = test.openquantumsafe.org - -[v3_intermediate_ca] -basicConstraints = critical, CA:true, pathlen:0 -keyUsage = critical, digitalSignature, cRLSign, keyCertSign -subjectKeyIdentifier = hash -authorityKeyIdentifier = keyid:always -certificatePolicies = 2.5.29.32.0 -extendedKeyUsage = clientAuth, serverAuth - -[v3_req] -basicConstraints = critical, CA:FALSE -keyUsage = critical, digitalSignature -extendedKeyUsage = serverAuth -subjectKeyIdentifier = hash -authorityKeyIdentifier = keyid:always -subjectAltName = @alt_names -certificatePolicies=2.23.140.1.2.1 - -[alt_names] -DNS.1 = test.openquantumsafe.org diff --git a/nginx/fulltest-provider/genconfig.py b/nginx/fulltest-provider/genconfig.py deleted file mode 100644 index 72e61fc7..00000000 --- a/nginx/fulltest-provider/genconfig.py +++ /dev/null @@ -1,237 +0,0 @@ -import common -import os -import json -import oqsprovider_alglist - -# Script assumes nginx to have been built for this platform using build-ubuntu.sh - -############# Configuration section starting here - -# This is where the explanation HTML code is -TEMPLATE_FILE="index-template" -CHROMIUM_TEMPLATE_FILE="chromium-template" - -# This is where nginx is (to be) installed -BASEPATH="/opt/nginx/" - -# This is the (relative to BASEPATH) path of all certificates -PKIPATH="pki" - -# This is the port where all algorithms start to be present(ed) -STARTPORT=6000 - -# This is the local location of the OQS-enabled OpenSSL -OPENSSL="/opt/openssl/apps/openssl" - -# This is the local OQS-OpenSSL config file -OPENSSL_CNF="/opt/openssl/apps/openssl.cnf" - -# This is the fully-qualified domain name of the server to be set up -# Ensure this is in sync with contents of ext-csr.conf file -TESTFQDN="test.openquantumsafe.org" - -# This is the local folder where the root CA (key and cert) resides -CAROOTDIR="/rootca" - -# This is the file containing the SIG/KEM/port assignments -ASSIGNMENT_FILE="assignments.json" - -# The list of chromium-supported KEMs: -# TODO: this list needs to be updated after a new Chromium build -chromium_algs = ["p256_frodo640aes"] - -############# Functions starting here - -# Generate cert chain (server and CA for a given sig alg: -# srv crt/key wind up in '/_srv.crt|key -def gen_cert(_sig_alg): - sig_alg = _sig_alg[0] - # first check whether we already have a root CA; if not create it - if not os.path.exists(CAROOTDIR): - os.mkdir(CAROOTDIR) - common.run_subprocess([OPENSSL, 'req', '-x509', '-new', - '-newkey', "rsa:4096", - '-keyout', os.path.join(CAROOTDIR, "CA.key"), - '-out', os.path.join(CAROOTDIR, "CA.crt"), - '-nodes', - '-subj', '/CN=oqstest_CA', - '-days', '500', - '-config', OPENSSL_CNF]) - print("New root cert residing in %s." % (os.path.join(CAROOTDIR, "CA.crt"))) - - # first check whether we already have a PKI dir; if not create it - if not os.path.exists(PKIPATH): - os.mkdir(PKIPATH) - - # now generate suitable server keys signed by that root; adapt algorithm names to std ossl - if sig_alg == 'rsa3072': - ossl_sig_alg_arg = 'rsa:3072' - elif sig_alg == 'ecdsap256': - common.run_subprocess([OPENSSL, "ecparam", "-name", "prime256v1", "-out", os.path.join(PKIPATH, "prime256v1.pem")]) - ossl_sig_alg_arg = 'ec:{}'.format(os.path.join(PKIPATH, "prime256v1.pem")) - else: - ossl_sig_alg_arg = sig_alg - # generate intermediate CA key and CSR - common.run_subprocess([OPENSSL, 'req', '-new', - '-newkey', ossl_sig_alg_arg, - '-keyout', os.path.join(PKIPATH, '{}_interm.key'.format(sig_alg)), - '-out', os.path.join(PKIPATH, '{}_interm.csr'.format(sig_alg)), - '-nodes', - '-subj', '/CN=oqstest_intermediate_'+sig_alg, - '-config', OPENSSL_CNF]) - # sign the intermediate CA using the root - common.run_subprocess([OPENSSL, 'x509', '-req', - '-in', os.path.join(PKIPATH, '{}_interm.csr'.format(sig_alg)), - '-out', os.path.join(PKIPATH, '{}_interm.crt'.format(sig_alg)), - '-CA', os.path.join(CAROOTDIR, 'CA.crt'), - '-CAkey', os.path.join(CAROOTDIR, 'CA.key'), - '-CAcreateserial', - '-extfile', 'ext-csr.conf', - '-extensions', 'v3_intermediate_ca', - '-days', '366']) - # generate server key and CSR - common.run_subprocess([OPENSSL, 'req', '-new', - '-newkey', ossl_sig_alg_arg, - '-keyout', os.path.join(PKIPATH, '{}_srv.key'.format(sig_alg)), - '-out', os.path.join(PKIPATH, '{}_srv.csr'.format(sig_alg)), - '-nodes', - '-subj', '/CN='+TESTFQDN, - '-config', OPENSSL_CNF]) - # generate server cert off common root - common.run_subprocess([OPENSSL, 'x509', '-req', - '-in', os.path.join(PKIPATH, '{}_srv.csr'.format(sig_alg)), - '-out', os.path.join(PKIPATH, '{}_srv.crt'.format(sig_alg)), - '-CA', os.path.join(PKIPATH, '{}_interm.crt'.format(sig_alg)), - '-CAkey', os.path.join(PKIPATH, '{}_interm.key'.format(sig_alg)), - '-CAcreateserial', - '-extfile', 'ext-csr.conf', - '-extensions', 'v3_req', - '-days', '365']) - # append intermediate cert to server cert - with open(os.path.join(PKIPATH, '{}_srv.crt'.format(sig_alg)), 'a') as srv: - srv.write("\n") - with open(os.path.join(PKIPATH, '{}_interm.crt'.format(sig_alg))) as interm: - srv.write(interm.read()) - -def write_nginx_config(f, i, cf, port, _sig, k): - sig = _sig[0] - f.write("server {\n") - f.write(" listen 0.0.0.0:"+str(port)+" ssl;\n\n") - f.write(" server_name "+TESTFQDN+";\n") - f.write(" access_log "+BASEPATH+"logs/"+sig+"-access.log;\n") - f.write(" error_log "+BASEPATH+"logs/"+sig+"-error.log;\n\n") - f.write(" ssl_certificate "+BASEPATH+PKIPATH+"/"+sig+"_srv.crt;\n") - f.write(" ssl_certificate_key "+BASEPATH+PKIPATH+"/"+sig+"_srv.key;\n\n") - f.write(" ssl_protocols TLSv1.3;\n") - if k!="*" : - f.write(" ssl_ecdh_curve "+k+";\n") - f.write(" location / {\n") - f.write(" ssi on;\n") - f.write(" set $oqs_sig_name \""+sig+"\";\n") - f.write(" root html;\n") - f.write(" index success.html;\n") - f.write(" keepalive_timeout 0;\n") - f.write(" }\n\n") - - f.write("}\n\n") - # activate for more boring links-only display: - #i.write("
  • "+sig+"/"+k+" ("+str(port)+")
  • \n") - #if k in chromium_algs: - # cf.write("
  • "+sig+"/"+k+" ("+str(port)+")
  • \n") - - # deactivate if you don't like tables: - i.write("
    \n") - # chromium support discontinued - #if k in chromium_algs and not ("_" in sig and (sig.startswith("p") or (sig.startswith("rsa")))): - # cf.write("\n") - - -# generates nginx config -def gen_conf(filename, indexbasefilename, chromiumfilename): - port = STARTPORT - assignments={} - i = open(indexbasefilename, "w") - # chromium support discontinued - cf = None - #cf = open(chromiumfilename, "w") - # copy baseline templates - with open(TEMPLATE_FILE, "r") as tf: - for line in tf: - i.write(line) - #chromium support discontinued - #with open(CHROMIUM_TEMPLATE_FILE, "r") as ctf: - # for line in ctf: - # cf.write(line) - - with open(filename, "w") as f: - # baseline config - f.write("worker_processes auto;\n") - f.write("worker_rlimit_nofile 10000;\n") - f.write("events {\n") - f.write(" worker_connections 32000;\n") - f.write("}\n") - f.write("\n") - f.write("http {\n") - f.write(" include conf/mime.types;\n"); - f.write(" default_type application/octet-stream;\n") - f.write(" keepalive_timeout 65;\n\n") - # plain server for base information - f.write("server {\n") - f.write(" listen 80;\n") - f.write(" server_name "+TESTFQDN+";\n") - f.write(" access_log /opt/nginx/logs/80-access.log;\n") - f.write(" error_log /opt/nginx/logs/80-error.log;\n\n") - f.write(" location / {\n") - f.write(" root html;\n") - f.write(" index "+indexbasefilename+";\n") - f.write(" }\n") - f.write("}\n") - f.write("server {\n") - f.write(" listen 443 ssl;\n") - f.write(" server_name "+TESTFQDN+";\n") - f.write(" access_log /opt/nginx/logs/443-access.log;\n") - f.write(" error_log /opt/nginx/logs/443-error.log;\n\n") - f.write(" ssl_certificate /etc/letsencrypt/live/"+TESTFQDN+"/fullchain.pem;\n") - f.write(" ssl_certificate_key /etc/letsencrypt/live/"+TESTFQDN+"/privkey.pem;\n\n") - f.write(" ssl_protocols TLSv1.2 TLSv1.3;\n") - f.write(" location / {\n") - f.write(" root html;\n") - f.write(" index "+indexbasefilename+";\n") - f.write(" }\n") - f.write("}\n") - - f.write("\n") - for sig in oqsprovider_alglist.signatures: - assignments[sig[0]]={} - assignments[sig[0]]["*"]=port - write_nginx_config(f, i, cf, port, sig, "*") - port = port+1 - for kex in oqsprovider_alglist.key_exchanges: - # replace oqs_kem_default with X25519: - if kex[0]=='oqs_kem_default': - write_nginx_config(f, i, cf, port, sig, "X25519") - assignments[sig[0]][kex[0]]=port - port = port+1 - elif kex[1] == sig[1] or sig[1] == 0: # only add if the sig and kex security levels match or sig[1]==0 (rsa/ecdsa) - write_nginx_config(f, i, cf, port, sig, kex[0]) - assignments[sig[0]][kex[0]]=port - port = port+1 - f.write("}\n") - # deactivate if you don't like tables: - i.write("
    Signature algorithmKey exchange algorithmPortLink
    "+sig+""+k+""+str(port)+""+sig+"/"+k+"
    "+sig+""+k+""+str(port)+""+sig+"/"+k+"
    \n") - i.write("\n") - i.close() - #cf.write("\n") - #cf.write("\n") - #cf.close() - with open(ASSIGNMENT_FILE, 'w') as outfile: - json.dump(assignments, outfile) - -def main(): - # first generate certs for all supported sig algs: - for sig in oqsprovider_alglist.signatures: - gen_cert(sig) - # now do conf and HTML files - gen_conf("interop.conf", "index-base.html", "chromium-base.html") - -main() diff --git a/nginx/fulltest-provider/index-template b/nginx/fulltest-provider/index-template deleted file mode 100644 index 1a61e65c..00000000 --- a/nginx/fulltest-provider/index-template +++ /dev/null @@ -1,92 +0,0 @@ - - - - -Open Quantum Safe interop test server for quantum-safe cryptography - - -

    Open Quantum Safe interop test server for quantum-safe cryptography

    -

    Purpose

    - -

    This server is an NGINX instance enhanced with support for quantum-safe cryptography (QSC) using software packages provided by the Open Quantum Safe project (OQS).

    - -

    In order to provide a means for clients to test interoperability with this QSC-enhanced software and the QSC algorithms contained it features separate ports for all QSC signature/key exchange algorithm combinations supported by the current OQS distribution.

    - -

    Specification details

    - -

    This nginx server supports

    - - -

    This corresponds to the OQS release version LIBOQS_RELEASE and oqs-provider version OQSPROVIDER_RELEASE.

    - -

    These specifications should not be taken as a standard, de facto and otherwise, and are subject to change at any time.

    - -

    More details are available at Github.

    - -

    Caveats

    - -
      -
    1. This test server by no means should be taken as containing production-ready software. See disclaimer. Its purpose is simply to provide a best-effort facility to allow anyone to "test-drive" QSC software packages including testing protocol level interoperability.
    2. - -
    3. When using the OQS-enabled Chromium build to access this web site, please heed its usage instructions. -
    4. When using the OQS-enabled GNOME Web/epiphany browser to access this web site, all ports can be accessed, provided the browser is suitably started enabling the algorithms of interest. Please read the documentation how to do this. -
    - -

    Certificates

    - -

    Each test port provides TLS server authentication using a server certificate generated using the listed QSC-signature algorithm. All server certificates are signed by a common CA certificate using conventional (RSA) cryptography. This certificate is available for download here.

    - -

    Testing procedure

    - -

    While we cannot prescribe how this test infrastructure is used we can show how it can be utilized using the OQS software made available ready-build at Docker Hub adding suggestions how other QSC-TLS implementations could check interoperability.

    - -
      -
    1. If not already done, download the test CA certificate from here to the directory you want to execute your tests from.
    2. -
    3. Select the algorithm combination to be tested from the list below. Assume this is sig/kex (port).
    4. -
    5. Connect to the corresponding port with a QSC-enabled client side software, e.g., curl. Using a ready-made docker image this could be facilitated by running
      docker run -v `pwd`:/ca -it openquantumsafe/curl:LIBOQS_RELEASE curl --cacert /ca/CA.crt https://test.openquantumsafe.org:port --curves kex
      Be sure to insert the port and kex values chosen above.
      The test will be successful if a web page indicating successful connection establishment (and display of the OQS algorithm combination configured as well as the client-supported key exchange mechanism) is received.
    6. -
    - -

    Notes:

    -
      -
    1. The instructions above assume a local installation of Docker.
    2. -
    3. Another equally valid approach would be to build all required software from source and then execute it locally. Examples for this can be found in the OQS Github repository.

      -

      In this way, you could for example verify correct operation of all components using openssl's s_client function by running

      echo "GET /" | openssl s_client -CAfile CA.crt --connect test.openquantumsafe.org:port --curves kex
      Again, values for port and kex must be suitably set.

    4. -
    5. Using "openssl s_client" has the additional benefit that it also displays the actual algorithms utilized: Server Temp Key describes the key exchange algorithm and Peer signature type the signature algorithm actually used.
    6. -
    7. The OQS docker hub containers also provide a ready-made QSC-openssl distribution facilitating this test: You can do this for example with this command:
      docker run -v `pwd`:/ca -it openquantumsafe/curl:LIBOQS_RELEASE openssl s_client --connect test.openquantumsafe.org:6000 -CAfile /ca/CA.crt 
      Then issue the GET / command on the command line to retrieve an information page.
    8. -
    9. The OQS docker images are pre-loaded with the test CA certificate which allow simplified testing bypassing the need to first obtain the test CA certificate and mounting this into the docker image. Therefore, testing a specific algorithm can be done simply without any preparation by running
      docker run -it openquantumsafe/curl:LIBOQS_RELEASE curl --cacert /opt/oqssa/oqs-testca.pem https://test.openquantumsafe.org:port --curves kex
    10. -
    - -

    List of all supported QSC Signature / Key Exchange algorithms

    - -

    The list below provides links to the entry points of all OQS signature / key exchange algorithm combinations supported.

    - -

    For automated testing, a JSON file encoding all available SIG/KEM combinations and the respective ports where they can be found is available for download here. We explicitly want to warn that algorithm/port combinations are subject to change. Be sure to download the most current JSON file before testing.

    - - - - - - - - - diff --git a/nginx/fulltest-provider/success.htm b/nginx/fulltest-provider/success.htm deleted file mode 100644 index 7203eade..00000000 --- a/nginx/fulltest-provider/success.htm +++ /dev/null @@ -1,16 +0,0 @@ - - - -Open Quantum Safe interop test server for quantum-safe cryptography - - -

    -Successfully connected using --! -

    - -Client-side KEM algorithm(s) indicated: - - - - diff --git a/nginx/fulltest-provider/testrun.py b/nginx/fulltest-provider/testrun.py deleted file mode 100644 index e64c2d15..00000000 --- a/nginx/fulltest-provider/testrun.py +++ /dev/null @@ -1,28 +0,0 @@ -import json -import sys -import subprocess -import os - -# Parameter checks already done in shellscript - -with open("assignments.json", "r") as f: - jsoncontents = f.read(); - -assignments = json.loads(jsoncontents) -for sig in assignments: - print("Testing %s:" % (sig)) - for kem in assignments[sig]: - # assemble testing command - cmd = "docker run -v "+os.path.abspath(os.getcwd())+"/ca:/ca -it "+sys.argv[1]+" curl --cacert /ca/CA.crt https://test.openquantumsafe.org:"+str(assignments[sig][kem]) - if kem!="*": # don't prescribe KEM - cmd=cmd+" --curves "+kem - dockerrun = subprocess.run(cmd.split(" "),stdout=subprocess.PIPE,stderr=subprocess.PIPE) - if dockerrun.returncode != 0 or not (b"Successfully" in dockerrun.stdout): - print("Error executing %s (Output: %s). Terminating." % (cmd, dockerrun.stdout)) - exit(1) - else: - print(" Tested KEM %s successfully." % (kem)) - print(" Successfully concluded testing "+sig) -print("All tests successfully passed.") - - diff --git a/nginx/fulltest-provider/testrun.sh b/nginx/fulltest-provider/testrun.sh deleted file mode 100755 index b9a28923..00000000 --- a/nginx/fulltest-provider/testrun.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash - -# Arg1 is docker image to use as client -if [ "$#" -ne 1 ]; then - echo "Usage: ${0} . Exiting." - exit 1 -fi - -# prepare test -rm -rf ca assignments.json* -mkdir ca -# pull current CA cert -cd ca -wget https://test.openquantumsafe.org/CA.crt -cd .. - -# pull list of algs/ports -wget https://test.openquantumsafe.org/assignments.json - -# execute test -python3 testrun.py ${1} diff --git a/nginx/fulltest-provider/Dockerfile b/nginx/fulltest/Dockerfile similarity index 100% rename from nginx/fulltest-provider/Dockerfile rename to nginx/fulltest/Dockerfile diff --git a/nginx/fulltest-provider/OsslAlgParser.scala b/nginx/fulltest/OsslAlgParser.scala similarity index 100% rename from nginx/fulltest-provider/OsslAlgParser.scala rename to nginx/fulltest/OsslAlgParser.scala diff --git a/nginx/fulltest/README.md b/nginx/fulltest/README.md index fa135d33..9b824436 100644 --- a/nginx/fulltest/README.md +++ b/nginx/fulltest/README.md @@ -4,45 +4,40 @@ This folder contains all scripts to [build a QSC-enabled nginx server running on *Note*: These scripts assume - coherent definition of test server FQDN as TESTFQDN in `genconfig.py` and `ext-csr.conf` files: By default "test.openquantumsafe.org" is set. -- presence of oqs-openssl common definitions file `common.py` (as stored at https://raw.githubusercontent.com/open-quantum-safe/openssl/OQS-OpenSSL_1_1_1-stable/oqs-test/common.py). -- presence on the build machine of a writable folder `/opt/nginx` for test-build (and local testing) +- presence of oqs-openssl common definitions file `common.py` (as stored at https://raw.githubusercontent.com/open-quantum-safe/oqs-provider/main/scripts/common.py). +- presence of Docker on the build machine to run the build process, the guest OS needs to be able to mount host directories for Docker (i.e. on Linux, SELinux permissions might be needed). - presence on the target deploy server (i.e., at the machine designated at TESTFQDN) of a properly deployed [LetsEncrypt server certificate](https://letsencrypt.org/getting-started). -By default, the server is built to a specific set of versions of `liboqs`, `oqs-openssl` and `nginx`. These versions are encoded in `build-ubuntu.sh` and may be changed/upgraded there. +By default, the server is built to a specific set of versions of `liboqs`, `openssl`, `oqs-provider` and `nginx`. These versions are encoded in `build-ubuntu.sh` and may be changed/upgraded there. ### HOWTO -#### Option 1: Build and test server separate +#### Build and deploy test server On build machine run ``` -./build-ubuntu.sh install -./package.sh -scp /opt/nginx/oqs-nginx.tgz yourid@yourserver:yourpath +./build-ubuntu.sh +scp oqs-nginx-{LIBOQS_VERSION}.tgz yourid@yourserver:yourpath ``` At 'yourserver' run: ``` -cd /opt/nginx && tar xzvf yourpath/oqs-nginx.tgz +cd / && tar xzvf yourpath/oqs-nginx-{LIBOQS_VERSION}.tgz +cd /opt/nginx /opt/nginx/sbin/nginx -c interop.conf ``` -#### Option 2: Building on test server - -``` -./build-ubuntu.sh install -``` - -Leave away the `install` option to first do a test-build, e.g., if executed on a live installation. +Note that, the oqs-nginx-{LIBOQS_VERSION}.tgz package contains all required configuration files and QSC certificates. **Unpacking the archive may overwrite an existing installation's configuration files. Use with care on a live server.** +#### Activation -#### First-time execution +Execute `OPENSSL_CONF=/opt/openssl/.openssl/ssl/openssl.cnf /opt/nginx/sbin/nginx -c /opt/nginx/interop.conf` to start the test server. -`python3 genconfig.py` generates all required QSC certificates. Execute this at the first installation and/or if/when algorithms supported by liboqs have changed since the last installation. **This script overwrites an existing installation's configuration files. Use with care on a live server.** Be sure to have the directory `pki` available/created: For example environmental setup, see e.g., [package.sh](package.sh). +*Note*: From nginx version 1.25.2, nginx does not try to load OpenSSL configuration if the --with-openssl option was used to build OpenSSL. We therefore have to set the `OPENSSL_CONF` environment variable when activating nginx. -#### Activation +*Note*: As the server may open many ports, the server may need to be configured to permit this, e.g., using `ulimit -S -n 4096`. -Execute `/opt/nginx/sbin/nginx -c /opt/nginx/interop.conf` to start the test server. +#### Test run -*Note*: As the server opens thousands of ports, the server may need to be configured to permit this, e.g., using `ulimit -S -n 4096`. +The `testrun.sh` script runs test connections against all ports configured by the server. To run the script, execute `testrun.sh openquantumsafe/curl:`. The compatible `` tag corresponds to `LIBOQS_VERSION` configured in the [Dockerfile](https://github.com/open-quantum-safe/oqs-demos/blob/main/nginx/fulltest/Dockerfile). diff --git a/nginx/fulltest/build-ubuntu.sh b/nginx/fulltest/build-ubuntu.sh deleted file mode 100755 index fb98480a..00000000 --- a/nginx/fulltest/build-ubuntu.sh +++ /dev/null @@ -1,55 +0,0 @@ -#!/bin/bash - -# defines the install path -export NGINX_PATH=/opt/nginx - -# define the nginx version to include -export NGINX_VERSION=1.21.5 - -# define the OQS releases to use; unset to deploy main branch -export LIBOQS_RELEASE=0.7.2 - -# defines the OQS-OpenSSL version to use; be sure to match with liboqs version -export OPENSSL_RELEASE=OQS-OpenSSL-1_1_1-stable-snapshot-2022-08 - -# Temporary openssl build path; keep in synch with genconfig.py -export OPENSSL_PATH=/tmp/opt/openssl - -# Define the degree of parallelism when building the image; leave the number away only if you know what you are doing -export MAKE_DEFINES="-j 4" - -# prerequisites: -sudo apt install -y libtool automake autoconf cmake make openssl git wget libssl-dev libpcre3-dev - -# get OQS sources -rm -rf /tmp/opt && mkdir /tmp/opt && cd /tmp/opt -if [ -z "$LIBOQS_RELEASE" ]; then -git clone --depth 1 --branch main https://github.com/open-quantum-safe/liboqs && \ -git clone --depth 1 --branch OQS-OpenSSL_1_1_1-stable https://github.com/open-quantum-safe/openssl -else -echo "Deploying stable liboqs release ${LIBOQS_RELEASE}" -wget https://github.com/open-quantum-safe/liboqs/archive/${LIBOQS_RELEASE}.tar.gz && tar xzvf ${LIBOQS_RELEASE}.tar.gz && mv liboqs-${LIBOQS_RELEASE} liboqs && \ -wget https://github.com/open-quantum-safe/openssl/archive/${OPENSSL_RELEASE}.tar.gz && tar xzvf ${OPENSSL_RELEASE}.tar.gz && mv openssl-${OPENSSL_RELEASE} openssl -fi -wget nginx.org/download/nginx-${NGINX_VERSION}.tar.gz && tar -zxvf nginx-${NGINX_VERSION}.tar.gz; - -# build liboqs (static only) -cd /tmp/opt/liboqs -mkdir build-static && cd build-static && cmake ${LIBOQS_BUILD_DEFINES} -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX=${OPENSSL_PATH}/oqs .. && make ${MAKE_DEFINES} && make install - -# build nginx (which builds OQS-OpenSSL) -cd /tmp/opt/nginx-${NGINX_VERSION} -./configure --prefix=${NGINX_PATH} \ - --with-debug \ - --with-http_ssl_module --with-openssl=${OPENSSL_PATH} \ - --with-stream_ssl_module \ - --without-http_gzip_module \ - --with-cc-opt=-I${OPENSSL_PATH}/oqs/include \ - --with-ld-opt="-L${OPENSSL_PATH}/oqs/lib" && \ - sed -i 's/libcrypto.a/libcrypto.a -loqs/g' objs/Makefile && \ - make ${MAKE_DEFINES} && make modules ; - -if [ $# -eq 1 ] && [ $1 = "install" ]; then - make install -fi - diff --git a/nginx/fulltest-provider/build_ubuntu.sh b/nginx/fulltest/build_ubuntu.sh similarity index 100% rename from nginx/fulltest-provider/build_ubuntu.sh rename to nginx/fulltest/build_ubuntu.sh diff --git a/nginx/fulltest/chromium-template b/nginx/fulltest/chromium-template index e0d7ba83..abee3f2a 100644 --- a/nginx/fulltest/chromium-template +++ b/nginx/fulltest/chromium-template @@ -32,12 +32,12 @@ tr:nth-child(even) {

    This nginx server supports

      -
    • the TLS1.3 specification with QSC enhancement as specified in https://tools.ietf.org/html/draft-ietf-tls-hybrid-design-00
    • -
    • Code points/curve IDs of KEM algorithms are implemented with the highest numbers available for each algorithm listed here.
    • -
    • Code points/OIDs of SIG algorithms are implemented with the highest numbers available for each algorithm as listed here.
    • +
    • the TLS1.3 specification with QSC enhancement as specified in https://tools.ietf.org/html/draft-ietf-tls-hybrid-design-06
    • +
    • Code points/curve IDs of KEM algorithms are implemented with the highest numbers available for each algorithm listed here.
    • +
    • Code points/OIDs of SIG algorithms are implemented with the highest numbers available for each algorithm as listed here.
    -

    This corresponds to the OQS release version LIBOQS_RELEASE

    +

    This corresponds to the OQS release version LIBOQS_RELEASE and oqs-provider version OQSPROVIDER_RELEASE.

    These specifications should not be taken as a standard, de facto and otherwise, and are subject to change at any time.

    diff --git a/nginx/fulltest-provider/common.py b/nginx/fulltest/common.py similarity index 100% rename from nginx/fulltest-provider/common.py rename to nginx/fulltest/common.py diff --git a/nginx/fulltest/ext-csr.conf b/nginx/fulltest/ext-csr.conf index 09a363c0..b4fc0617 100644 --- a/nginx/fulltest/ext-csr.conf +++ b/nginx/fulltest/ext-csr.conf @@ -6,9 +6,22 @@ prompt = no [req_distinguished_name] CN = test.openquantumsafe.org +[v3_intermediate_ca] +basicConstraints = critical, CA:true, pathlen:0 +keyUsage = critical, digitalSignature, cRLSign, keyCertSign +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always +certificatePolicies = 2.5.29.32.0 +extendedKeyUsage = clientAuth, serverAuth + [v3_req] -keyUsage = nonRepudiation, digitalSignature, keyEncipherment +basicConstraints = critical, CA:FALSE +keyUsage = critical, digitalSignature extendedKeyUsage = serverAuth +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always subjectAltName = @alt_names +certificatePolicies=2.23.140.1.2.1 + [alt_names] DNS.1 = test.openquantumsafe.org diff --git a/nginx/fulltest/genconfig.py b/nginx/fulltest/genconfig.py index 4b42ef33..200edb91 100644 --- a/nginx/fulltest/genconfig.py +++ b/nginx/fulltest/genconfig.py @@ -1,6 +1,7 @@ import common import os import json +import oqsprovider_alglist # Script assumes nginx to have been built for this platform using build-ubuntu.sh @@ -20,29 +21,31 @@ STARTPORT=6000 # This is the local location of the OQS-enabled OpenSSL -OPENSSL="/tmp/opt/openssl/apps/openssl" +OPENSSL="/opt/openssl/apps/openssl" # This is the local OQS-OpenSSL config file -OPENSSL_CNF="/tmp/opt/openssl/apps/openssl.cnf" +OPENSSL_CNF="/opt/openssl/apps/openssl.cnf" # This is the fully-qualified domain name of the server to be set up # Ensure this is in sync with contents of ext-csr.conf file TESTFQDN="test.openquantumsafe.org" # This is the local folder where the root CA (key and cert) resides -CAROOTDIR="root" +CAROOTDIR="/rootca" # This is the file containing the SIG/KEM/port assignments ASSIGNMENT_FILE="assignments.json" # The list of chromium-supported KEMs: -chromium_algs = ["p256_bikel1", "p256_frodo640aes", "p256_kyber512", "p256_ntru_hps2048509", "p256_lightsaber"] +# TODO: this list needs to be updated after a new Chromium build +chromium_algs = ["p256_frodo640aes"] ############# Functions starting here # Generate cert chain (server and CA for a given sig alg: # srv crt/key wind up in '/_srv.crt|key -def gen_cert(sig_alg): +def gen_cert(_sig_alg): + sig_alg = _sig_alg[0] # first check whether we already have a root CA; if not create it if not os.path.exists(CAROOTDIR): os.mkdir(CAROOTDIR) @@ -60,7 +63,7 @@ def gen_cert(sig_alg): if not os.path.exists(PKIPATH): os.mkdir(PKIPATH) - # now generate suitable server keys signed by that root; adapt algorithm names to std ossl + # now generate suitable server keys signed by that root; adapt algorithm names to std ossl if sig_alg == 'rsa3072': ossl_sig_alg_arg = 'rsa:3072' elif sig_alg == 'ecdsap256': @@ -68,6 +71,24 @@ def gen_cert(sig_alg): ossl_sig_alg_arg = 'ec:{}'.format(os.path.join(PKIPATH, "prime256v1.pem")) else: ossl_sig_alg_arg = sig_alg + # generate intermediate CA key and CSR + common.run_subprocess([OPENSSL, 'req', '-new', + '-newkey', ossl_sig_alg_arg, + '-keyout', os.path.join(PKIPATH, '{}_interm.key'.format(sig_alg)), + '-out', os.path.join(PKIPATH, '{}_interm.csr'.format(sig_alg)), + '-nodes', + '-subj', '/CN=oqstest_intermediate_'+sig_alg, + '-config', OPENSSL_CNF]) + # sign the intermediate CA using the root + common.run_subprocess([OPENSSL, 'x509', '-req', + '-in', os.path.join(PKIPATH, '{}_interm.csr'.format(sig_alg)), + '-out', os.path.join(PKIPATH, '{}_interm.crt'.format(sig_alg)), + '-CA', os.path.join(CAROOTDIR, 'CA.crt'), + '-CAkey', os.path.join(CAROOTDIR, 'CA.key'), + '-CAcreateserial', + '-extfile', 'ext-csr.conf', + '-extensions', 'v3_intermediate_ca', + '-days', '366']) # generate server key and CSR common.run_subprocess([OPENSSL, 'req', '-new', '-newkey', ossl_sig_alg_arg, @@ -80,14 +101,20 @@ def gen_cert(sig_alg): common.run_subprocess([OPENSSL, 'x509', '-req', '-in', os.path.join(PKIPATH, '{}_srv.csr'.format(sig_alg)), '-out', os.path.join(PKIPATH, '{}_srv.crt'.format(sig_alg)), - '-CA', os.path.join(CAROOTDIR, 'CA.crt'), - '-CAkey', os.path.join(CAROOTDIR, 'CA.key'), + '-CA', os.path.join(PKIPATH, '{}_interm.crt'.format(sig_alg)), + '-CAkey', os.path.join(PKIPATH, '{}_interm.key'.format(sig_alg)), '-CAcreateserial', - '-extfile', 'ext-csr.conf', + '-extfile', 'ext-csr.conf', '-extensions', 'v3_req', '-days', '365']) - -def write_nginx_config(f, i, cf, port, sig, k): + # append intermediate cert to server cert + with open(os.path.join(PKIPATH, '{}_srv.crt'.format(sig_alg)), 'a') as srv: + srv.write("\n") + with open(os.path.join(PKIPATH, '{}_interm.crt'.format(sig_alg))) as interm: + srv.write(interm.read()) + +def write_nginx_config(f, i, cf, port, _sig, k): + sig = _sig[0] f.write("server {\n") f.write(" listen 0.0.0.0:"+str(port)+" ssl;\n\n") f.write(" server_name "+TESTFQDN+";\n") @@ -99,11 +126,11 @@ def write_nginx_config(f, i, cf, port, sig, k): if k!="*" : f.write(" ssl_ecdh_curve "+k+";\n") f.write(" location / {\n") - f.write(" ssi on;\n") - if k!="*" : - f.write(" set $oqs_alg_name \""+sig+"-"+k+"\";\n") + f.write(" ssi on;\n") + f.write(" set $oqs_sig_name \""+sig+"\";\n") f.write(" root html;\n") f.write(" index success.html;\n") + f.write(" keepalive_timeout 0;\n") f.write(" }\n\n") f.write("}\n\n") @@ -114,8 +141,9 @@ def write_nginx_config(f, i, cf, port, sig, k): # deactivate if you don't like tables: i.write("
    \n") - if k in chromium_algs and not ("_" in sig and (sig.startswith("p") or (sig.startswith("rsa")))): - cf.write("\n") + # don't explicitly state Chromium compatibility + #if k in chromium_algs and not ("_" in sig and (sig.startswith("p") or (sig.startswith("rsa")))): + # cf.write("\n") # generates nginx config @@ -123,14 +151,17 @@ def gen_conf(filename, indexbasefilename, chromiumfilename): port = STARTPORT assignments={} i = open(indexbasefilename, "w") - cf = open(chromiumfilename, "w") + # don't explicitly state Chromium compatibility + cf = None + #cf = open(chromiumfilename, "w") # copy baseline templates with open(TEMPLATE_FILE, "r") as tf: for line in tf: i.write(line) - with open(CHROMIUM_TEMPLATE_FILE, "r") as ctf: - for line in ctf: - cf.write(line) + # don't explicitly state Chromium compatibility + #with open(CHROMIUM_TEMPLATE_FILE, "r") as ctf: + # for line in ctf: + # cf.write(line) with open(filename, "w") as f: # baseline config @@ -170,31 +201,35 @@ def gen_conf(filename, indexbasefilename, chromiumfilename): f.write("}\n") f.write("\n") - for sig in common.signatures: - assignments[sig]={} - assignments[sig]["*"]=port + for sig in oqsprovider_alglist.signatures: + assignments[sig[0]]={} + assignments[sig[0]]["*"]=port write_nginx_config(f, i, cf, port, sig, "*") port = port+1 - for kex in common.key_exchanges: - # replace oqs_kem_default with X25519: - k = "X25519" if kex=='oqs_kem_default' else kex - write_nginx_config(f, i, cf, port, sig, k) - assignments[sig][k]=port - port = port+1 + for kex in oqsprovider_alglist.key_exchanges: + # replace oqs_kem_default with X25519: + if kex[0]=='oqs_kem_default': + write_nginx_config(f, i, cf, port, sig, "X25519") + assignments[sig[0]][kex[0]]=port + port = port+1 + elif kex[1] == sig[1] or sig[1] == 0: # only add if the sig and kex security levels match or sig[1]==0 (rsa/ecdsa) + write_nginx_config(f, i, cf, port, sig, kex[0]) + assignments[sig[0]][kex[0]]=port + port = port+1 f.write("}\n") # deactivate if you don't like tables: i.write("
    Signature algorithmKey exchange algorithmPortLink
    "+sig+""+k+""+str(port)+""+sig+"/"+k+"
    "+sig+""+k+""+str(port)+""+sig+"/"+k+"
    "+sig+""+k+""+str(port)+""+sig+"/"+k+"
    \n") i.write("\n") i.close() - cf.write("\n") - cf.write("\n") - cf.close() + #cf.write("\n") + #cf.write("\n") + #cf.close() with open(ASSIGNMENT_FILE, 'w') as outfile: json.dump(assignments, outfile) def main(): # first generate certs for all supported sig algs: - for sig in common.signatures: + for sig in oqsprovider_alglist.signatures: gen_cert(sig) # now do conf and HTML files gen_conf("interop.conf", "index-base.html", "chromium-base.html") diff --git a/nginx/fulltest/index-template b/nginx/fulltest/index-template index 2d197c48..1a61e65c 100644 --- a/nginx/fulltest/index-template +++ b/nginx/fulltest/index-template @@ -32,12 +32,12 @@ tr:nth-child(even) {

    This nginx server supports

    -

    This corresponds to the OQS release version LIBOQS_RELEASE

    +

    This corresponds to the OQS release version LIBOQS_RELEASE and oqs-provider version OQSPROVIDER_RELEASE.

    These specifications should not be taken as a standard, de facto and otherwise, and are subject to change at any time.

    diff --git a/nginx/fulltest-provider/ngx_event_openssl.patch b/nginx/fulltest/ngx_event_openssl.patch similarity index 100% rename from nginx/fulltest-provider/ngx_event_openssl.patch rename to nginx/fulltest/ngx_event_openssl.patch diff --git a/nginx/fulltest/package.sh b/nginx/fulltest/package.sh deleted file mode 100755 index 592b3445..00000000 --- a/nginx/fulltest/package.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash - -# Script assumes nginx to have been built for this platform, e.g. using the build-ubuntu.sh script -NGINX_INSTALL_DIR=/opt/nginx - -# Set this to document support of specific version. Be sure to keep this in sync with what is specified in build-ubuntu.sh. -LIBOQS_RELEASE=0.7.2 - -# cleanup: retaining root CA! -rm -rf *.tgz pki common.py *.html interop.conf assignments.json - -# Obtain current list of algorithms -wget https://raw.githubusercontent.com/open-quantum-safe/openssl/OQS-OpenSSL_1_1_1-stable/oqs-test/common.py - -mkdir pki - -# Now generate config file, incl. CA and certs -python3 genconfig.py - -# Be sure to set the proper RELEASE version: -sed -i "s/LIBOQS_RELEASE/${LIBOQS_RELEASE}/g" index-base.html -sed -i "s/LIBOQS_RELEASE/${LIBOQS_RELEASE}/g" chromium-base.html - -# Now move all piece-parts in place -rm -rf ${NGINX_INSTALL_DIR}/pki -rm -rf ${NGINX_INSTALL_DIR}/logs/* -cp -R pki ${NGINX_INSTALL_DIR} -cp interop.conf ${NGINX_INSTALL_DIR} -mkdir -p ${NGINX_INSTALL_DIR}/html -cp *.html ${NGINX_INSTALL_DIR}/html -cp root/CA.crt ${NGINX_INSTALL_DIR}/html -cp success.htm ${NGINX_INSTALL_DIR}/html/success.html -cp assignments.json ${NGINX_INSTALL_DIR}/html/ - -cd ${NGINX_INSTALL_DIR} && tar czvf oqs-nginx-${LIBOQS_RELEASE}.tgz * -set +x -echo "copy ${NGINX_INSTALL_DIR}/oqs-nginx.tgz to server and extract at ${NGINX_INSTALL_DIR}. Start up with '${NGINX_INSTALL_DIR}/sbin/nginx -c interop.conf'" -echo "Possibly raise system wide limits by running ulimit -S -n 4096 or adding resource extensions like shown for example at https://docs.tigase.net/tigase-server/8.0.0-RC1/Administration_Guide/html_chunk/linuxhighload.html " diff --git a/nginx/fulltest/prepare.sh b/nginx/fulltest/prepare.sh deleted file mode 100755 index 789e255e..00000000 --- a/nginx/fulltest/prepare.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash - -# Script assumes nginx to have been built for this platform using the ../(nginx-)Dockerfile instructions -NGINX_INSTALL_DIR=/opt/nginx - -# cleanup; not deleting root CA! -rm -rf pki common.py *.html interop.conf - -# Obtain current list of algorithms -wget https://raw.githubusercontent.com/open-quantum-safe/openssl/OQS-OpenSSL_1_1_1-stable/oqs-test/common.py - -mkdir pki - -# Now generate config file -python3 genconfig.py - -# Now move it all in place -rm -rf ${NGINX_INSTALL_DIR}/pki -cp -R pki ${NGINX_INSTALL_DIR} -mkdir -p ${NGINX_INSTALL_DIR}/html -cp root/CA.crt ${NGINX_INSTALL_DIR}/html -cp interop.conf ${NGINX_INSTALL_DIR} -cp *.html ${NGINX_INSTALL_DIR}/html -cp assignments.json ${NGINX_INSTALL_DIR}/html -cp success.htm ${NGINX_INSTALL_DIR}/html/success.html -echo "start up nginx with 'nginx -c interop.conf'" diff --git a/nginx/fulltest/success.htm b/nginx/fulltest/success.htm index e1264f2b..7203eade 100644 --- a/nginx/fulltest/success.htm +++ b/nginx/fulltest/success.htm @@ -6,10 +6,11 @@

    Successfully connected using - -! +-!

    Client-side KEM algorithm(s) indicated: + +