From 59b4af44835e2babafe398040a280ed23e9b490e Mon Sep 17 00:00:00 2001 From: Michal Bajer Date: Fri, 20 May 2022 10:46:10 +0000 Subject: [PATCH] feat(secret): remove Validator/Verifier secret keys from repository - Remove validator sample CA keys hardcoded inside the repository. - Generate fresh ECDSA keys when starting up electricity-trade or discounted-asset-trade sample apps. - Add support for RSA CA keys in fabric-socketio validator. I couldn't find any trivial way of generating ECDSA self-signed certificate (without calling openssl cmdline, which seems poor from functional test perspective), so I've added support for RSA keys to simplify the tests. - Allow selection of jwt algorithm in fabric-socketio validator. It must correspond to the key used. - Update the READMEs, add short description of SSL config option of fabric-socketio validator. Closes: 2016 Closes: 2017 Depends on: 1977 Depends on: 2030 Signed-off-by: Michal Bajer --- .../Dockerfile | 2 +- .../config/validator-registry-config.yaml | 6 +- .../package.json | 7 +- .../script-start-ledgers.sh | 48 +++++- .../Dockerfile | 2 +- .../config/validator-registry-config.yaml | 4 +- .../package.json | 6 +- .../script-start-ledgers.sh | 46 ++++++ .../cactus_validator_socketio_indy/.gitignore | 3 +- .../cactus_validator_socketio_indy/Dockerfile | 4 +- .../cactus_validator_socketio_indy/README.md | 20 ++- .../post_install_script.py | 1 + .../sample-CA/connector.crt | 10 -- .../sample-CA/connector.priv | 8 - .../testcli/connector.crt | 1 - .../main/typescript/socketio-api-client.ts | 2 +- .../config/self-signed-pki-generator.ts | 20 +++ .../README.md | 4 + .../package.json | 2 + .../sample-config/CA/connector.crt | 10 -- .../sample-config/CA/connector.csr | 8 - .../sample-config/CA/connector.priv | 8 - .../sample-config/default.yaml | 9 + .../connector/ValidatorAuthentication.ts | 24 ++- .../fabric-socketio-connector.test.ts | 26 ++- .../tsconfig.json | 3 + .../sample-config/CA/connector.crt | 10 -- .../sample-config/CA/connector.csr | 8 - .../sample-config/CA/connector.priv | 8 - .../sample-config/CA/connector.crt | 10 -- .../sample-config/CA/connector.csr | 8 - .../sample-config/CA/connector.priv | 8 - packages/cactus-test-tooling/package.json | 4 +- .../pki/self-signed-pki-generator.ts | 155 ++++++++++++++++++ .../src/main/typescript/public-api.ts | 9 + 35 files changed, 353 insertions(+), 151 deletions(-) delete mode 100644 packages-python/cactus_validator_socketio_indy/sample-CA/connector.crt delete mode 100644 packages-python/cactus_validator_socketio_indy/sample-CA/connector.priv delete mode 120000 packages-python/cactus_validator_socketio_indy/testcli/connector.crt delete mode 100644 packages/cactus-plugin-ledger-connector-fabric-socketio/sample-config/CA/connector.crt delete mode 100644 packages/cactus-plugin-ledger-connector-fabric-socketio/sample-config/CA/connector.csr delete mode 100644 packages/cactus-plugin-ledger-connector-fabric-socketio/sample-config/CA/connector.priv delete mode 100644 packages/cactus-plugin-ledger-connector-go-ethereum-socketio/sample-config/CA/connector.crt delete mode 100644 packages/cactus-plugin-ledger-connector-go-ethereum-socketio/sample-config/CA/connector.csr delete mode 100644 packages/cactus-plugin-ledger-connector-go-ethereum-socketio/sample-config/CA/connector.priv delete mode 100644 packages/cactus-plugin-ledger-connector-sawtooth-socketio/sample-config/CA/connector.crt delete mode 100644 packages/cactus-plugin-ledger-connector-sawtooth-socketio/sample-config/CA/connector.csr delete mode 100644 packages/cactus-plugin-ledger-connector-sawtooth-socketio/sample-config/CA/connector.priv create mode 100644 packages/cactus-test-tooling/src/main/typescript/pki/self-signed-pki-generator.ts diff --git a/examples/cactus-example-discounted-asset-trade/Dockerfile b/examples/cactus-example-discounted-asset-trade/Dockerfile index 8eed6dea17..6198cdb831 100644 --- a/examples/cactus-example-discounted-asset-trade/Dockerfile +++ b/examples/cactus-example-discounted-asset-trade/Dockerfile @@ -17,7 +17,7 @@ RUN apt-get update \ # Note - indy_sdk:latest must be ABI compatible with this image OS COPY --from=indy-sdk-cli:latest /usr/lib/libindy.so /usr/lib/ -COPY ./package.json ./dist/yarn.lock ./dist/fabric-connector.crt ./dist/ethereum-connector.crt ./dist/indy-connector.crt ./ +COPY ./package.json ./dist/yarn.lock ./ RUN yarn add "${CACTUS_CMD_SOCKETIO_PATH}" "@hyperledger/cactus-verifier-client@${NPM_PKG_VERSION}" \ --production --ignore-engines --non-interactive --cache-folder ./.yarnCache && \ rm -rf ./.yarnCache diff --git a/examples/cactus-example-discounted-asset-trade/config/validator-registry-config.yaml b/examples/cactus-example-discounted-asset-trade/config/validator-registry-config.yaml index 9c0fabf439..f8ba020811 100644 --- a/examples/cactus-example-discounted-asset-trade/config/validator-registry-config.yaml +++ b/examples/cactus-example-discounted-asset-trade/config/validator-registry-config.yaml @@ -3,7 +3,7 @@ ledgerPluginInfo: validatorID: 84jUisrs validatorType: legacy-socketio validatorURL: https://ethereum-validator:5050 - validatorKeyPath: /root/cactus/ethereum-connector.crt + validatorKeyPath: /etc/cactus/connector-go-ethereum-socketio/CA/connector.crt maxCounterRequestID: 100 syncFunctionTimeoutMillisecond: 5000 socketOptions: @@ -42,7 +42,7 @@ ledgerPluginInfo: validatorID: r9IS4dDf validatorType: legacy-socketio validatorURL: https://fabric-socketio-validator:5040 - validatorKeyPath: /root/cactus/fabric-connector.crt + validatorKeyPath: /etc/cactus/connector-fabric-socketio/CA/connector.crt maxCounterRequestID: 100 syncFunctionTimeoutMillisecond: 5000 socketOptions: @@ -57,7 +57,7 @@ ledgerPluginInfo: validatorID: 3PfTJw8g validatorType: legacy-socketio validatorURL: http://indy-validator-nginx:10080 - validatorKeyPath: /root/cactus/indy-connector.crt + validatorKeyPath: /etc/cactus/validator_socketio_indy/CA/connector.crt maxCounterRequestID: 100 syncFunctionTimeoutMillisecond: 5000 socketOptions: diff --git a/examples/cactus-example-discounted-asset-trade/package.json b/examples/cactus-example-discounted-asset-trade/package.json index eb5ab4476c..41f53f22ab 100644 --- a/examples/cactus-example-discounted-asset-trade/package.json +++ b/examples/cactus-example-discounted-asset-trade/package.json @@ -11,12 +11,7 @@ "build": "npm run build-ts && npm run build:dev:backend:postbuild", "build-ts": "tsc", "build_pip_indy_package": "cd ../../packages-python/cactus_validator_socketio_indy && python3 setup.py bdist_wheel", - "build:dev:backend:postbuild": "npm run copy-yarn-lock && npm run copy-validator-keys", - "copy-yarn-lock": "cp -f ../../yarn.lock ./dist/", - "copy-validator-keys": "npm run copy-fabric-key && npm run copy-ethereum-key && npm run copy-indy-key", - "copy-fabric-key": "cp -fr ../../packages/cactus-plugin-ledger-connector-fabric-socketio/sample-config/CA/connector.crt ./dist/fabric-connector.crt", - "copy-ethereum-key": "cp -fr ../../packages/cactus-plugin-ledger-connector-go-ethereum-socketio/sample-config/CA/connector.crt ./dist/ethereum-connector.crt", - "copy-indy-key": "cp -fr ../../packages-python/cactus_validator_socketio_indy/sample-CA/connector.crt ./dist/indy-connector.crt" + "build:dev:backend:postbuild": "cp -f ../../yarn.lock ./dist/" }, "dependencies": { "axios": "0.24.0", diff --git a/examples/cactus-example-discounted-asset-trade/script-start-ledgers.sh b/examples/cactus-example-discounted-asset-trade/script-start-ledgers.sh index 9dda439b08..80583b7f3c 100755 --- a/examples/cactus-example-discounted-asset-trade/script-start-ledgers.sh +++ b/examples/cactus-example-discounted-asset-trade/script-start-ledgers.sh @@ -13,6 +13,50 @@ export CACTUS_FABRIC_ALL_IN_ONE_CONTAINER_NAME="asset_trade_faio2x_testnet" export CACTUS_FABRIC_ALL_IN_ONE_VERSION="2.2.0" export CACTUS_FABRIC_TEST_LOOSE_MEMBERSHIP=1 +# Cert options +CERT_CURVE_NAME="prime256v1" +CERT_COUNTRY="JP" +CERT_STATE="Tokyo" +CERT_LOCALITY="Minato-Ku" +CERT_ORG="CactusSamples" + +# generate_certificate +function generate_certificate() { + # Check OpenSSL command existance + if ! openssl version > /dev/null; then + echo "Could not execute [openssl version], check if OpenSSL tool is available on the system." + exit 1; + fi + + # Check input parameters + ARGS_NUMBER=2 + if [ "$#" -lt "$ARGS_NUMBER" ]; then + echo "generate_certificate called with wrong number of arguments (expected - $ARGS_NUMBER, actual - $#)"; + exit 2 + fi + + common_name=$1 + destination=$2 + subject="/C=$CERT_COUNTRY/ST=$CERT_STATE/L=$CERT_LOCALITY/O=$CERT_ORG/CN=$common_name" + echo "Create new cert in '${destination}' with subject '${subject}'" + + # Crete destination path + if [ ! -d "$destination" ]; then + echo "Re-create destination dir..." + rm -rf "$destination" + mkdir -p "$destination" + fi + + keyPath="${destination}/connector.priv" + csrPath="${destination}/connector.csr" + certPath="${destination}/connector.crt" + + # Generate keys + openssl ecparam -genkey -name "$CERT_CURVE_NAME" -out "$keyPath" + openssl req -new -sha256 -key "$keyPath" -out "$csrPath" -subj "$subject" + openssl req -x509 -sha256 -days 365 -key "$keyPath" -in "$csrPath" -out "$certPath" +} + function start_fabric_testnet() { echo ">> start_fabric_testnet()" pushd "${ROOT_DIR}/tools/docker/fabric-all-in-one" @@ -54,6 +98,7 @@ function copy_fabric_validator_config() { echo ">> copy_fabric_validator_config()" cp -fr ${ROOT_DIR}/packages/cactus-plugin-ledger-connector-fabric-socketio/sample-config/* \ "${CONFIG_VOLUME_PATH}/connector-fabric-socketio/" + generate_certificate "FabricSocketIOCactusValidator" "${CONFIG_VOLUME_PATH}/connector-fabric-socketio/CA/" echo ">> copy_fabric_validator_config() done." echo ">> copy_fabric_wallet()" @@ -71,6 +116,7 @@ function copy_ethereum_validator_config() { echo ">> copy_ethereum_validator_config()" cp -fr ${ROOT_DIR}/packages/cactus-plugin-ledger-connector-go-ethereum-socketio/sample-config/* \ "${CONFIG_VOLUME_PATH}/connector-go-ethereum-socketio/" + generate_certificate "GoEthereumCactusValidator" "${CONFIG_VOLUME_PATH}/connector-go-ethereum-socketio/CA/" echo ">> copy_ethereum_validator_config() done." } @@ -91,7 +137,7 @@ function copy_indy_validator_config() { function copy_indy_validator_ca() { echo ">> copy_indy_validator_ca()" - cp -fr "${ROOT_DIR}/packages-python/cactus_validator_socketio_indy/sample-CA/" "${CONFIG_VOLUME_PATH}/validator_socketio_indy/CA" + generate_certificate "IndyCactusValidator" "${CONFIG_VOLUME_PATH}/validator_socketio_indy/CA/" echo ">> copy_indy_validator_ca() done." } diff --git a/examples/cactus-example-electricity-trade/Dockerfile b/examples/cactus-example-electricity-trade/Dockerfile index 79f31d6faf..6795b68371 100644 --- a/examples/cactus-example-electricity-trade/Dockerfile +++ b/examples/cactus-example-electricity-trade/Dockerfile @@ -6,7 +6,7 @@ ENV APP_HOME=/root/cactus WORKDIR ${APP_HOME} -COPY ./dist/yarn.lock ./package.json ./dist/ethereum-connector.crt ./dist/sawtooth-connector.crt ./ +COPY ./dist/yarn.lock ./package.json ./ RUN yarn add "${CACTUS_CMD_SOCKETIO_PATH}" "@hyperledger/cactus-verifier-client@${NPM_PKG_VERSION}" \ --production --ignore-engines --non-interactive --cache-folder ./.yarnCache && \ rm -rf ./.yarnCache diff --git a/examples/cactus-example-electricity-trade/config/validator-registry-config.yaml b/examples/cactus-example-electricity-trade/config/validator-registry-config.yaml index b99c3dbda6..7d19f200f8 100644 --- a/examples/cactus-example-electricity-trade/config/validator-registry-config.yaml +++ b/examples/cactus-example-electricity-trade/config/validator-registry-config.yaml @@ -3,7 +3,7 @@ ledgerPluginInfo: validatorID: 84jUisrs validatorType: legacy-socketio validatorURL: https://ethereum-validator:5050 - validatorKeyPath: /root/cactus/ethereum-connector.crt + validatorKeyPath: /etc/cactus/connector-go-ethereum-socketio/CA/connector.crt maxCounterRequestID: 100 syncFunctionTimeoutMillisecond: 5000 socketOptions: @@ -42,7 +42,7 @@ ledgerPluginInfo: validatorID: sUr7d10R validatorType: legacy-socketio validatorURL: https://sawtooth-validator:5140 - validatorKeyPath: /root/cactus/sawtooth-connector.crt + validatorKeyPath: /etc/cactus/connector-sawtooth-socketio/CA/connector.crt maxCounterRequestID: 100 syncFunctionTimeoutMillisecond: 5000 socketOptions: diff --git a/examples/cactus-example-electricity-trade/package.json b/examples/cactus-example-electricity-trade/package.json index c06ffb50c1..442b3a7f13 100644 --- a/examples/cactus-example-electricity-trade/package.json +++ b/examples/cactus-example-electricity-trade/package.json @@ -10,11 +10,7 @@ "start": "docker-compose build && docker-compose up", "build": "npm run build-ts && npm run build:dev:backend:postbuild", "build-ts": "tsc", - "build:dev:backend:postbuild": "npm run copy-yarn-lock && npm run copy-validator-keys", - "copy-yarn-lock": "cp -f ../../yarn.lock ./dist/", - "copy-validator-keys": "npm run copy-ethereum-key && npm run copy-sawtooth-key", - "copy-ethereum-key": "cp -fr ../../packages/cactus-plugin-ledger-connector-go-ethereum-socketio/sample-config/CA/connector.crt ./dist/ethereum-connector.crt", - "copy-sawtooth-key": "cp -fr ../../packages/cactus-plugin-ledger-connector-sawtooth-socketio/sample-config/CA/connector.crt ./dist/sawtooth-connector.crt" + "build:dev:backend:postbuild": "cp -f ../../yarn.lock ./dist/" }, "dependencies": { "@types/node": "14.18.12", diff --git a/examples/cactus-example-electricity-trade/script-start-ledgers.sh b/examples/cactus-example-electricity-trade/script-start-ledgers.sh index ef3c995bb0..01f736adce 100755 --- a/examples/cactus-example-electricity-trade/script-start-ledgers.sh +++ b/examples/cactus-example-electricity-trade/script-start-ledgers.sh @@ -7,6 +7,50 @@ set -e ROOT_DIR="../.." # Path to cactus root dir CONFIG_VOLUME_PATH="./etc/cactus" # Docker volume with shared configuration +# Cert options +CERT_CURVE_NAME="prime256v1" +CERT_COUNTRY="JP" +CERT_STATE="Tokyo" +CERT_LOCALITY="Minato-Ku" +CERT_ORG="CactusSamples" + +# generate_certificate +function generate_certificate() { + # Check OpenSSL command existance + if ! openssl version > /dev/null; then + echo "Could not execute [openssl version], check if OpenSSL tool is available on the system." + exit 1; + fi + + # Check input parameters + ARGS_NUMBER=2 + if [ "$#" -lt "$ARGS_NUMBER" ]; then + echo "generate_certificate called with wrong number of arguments (expected - $ARGS_NUMBER, actual - $#)"; + exit 2 + fi + + common_name=$1 + destination=$2 + subject="/C=$CERT_COUNTRY/ST=$CERT_STATE/L=$CERT_LOCALITY/O=$CERT_ORG/CN=$common_name" + echo "Create new cert in '${destination}' with subject '${subject}'" + + # Crete destination path + if [ ! -d "$destination" ]; then + echo "Re-create destination dir..." + rm -rf "$destination" + mkdir -p "$destination" + fi + + keyPath="${destination}/connector.priv" + csrPath="${destination}/connector.csr" + certPath="${destination}/connector.crt" + + # Generate keys + openssl ecparam -genkey -name "$CERT_CURVE_NAME" -out "$keyPath" + openssl req -new -sha256 -key "$keyPath" -out "$csrPath" -subj "$subject" + openssl req -x509 -sha256 -days 365 -key "$keyPath" -in "$csrPath" -out "$certPath" +} + function start_ethereum_testnet() { pushd "${ROOT_DIR}/tools/docker/geth-testnet" ./script-start-docker.sh @@ -17,6 +61,7 @@ function copy_ethereum_validator_config() { echo ">> copy_ethereum_validator_config()" cp -fr ${ROOT_DIR}/packages/cactus-plugin-ledger-connector-go-ethereum-socketio/sample-config/* \ "${CONFIG_VOLUME_PATH}/connector-go-ethereum-socketio/" + generate_certificate "GoEthereumCactusValidator" "${CONFIG_VOLUME_PATH}/connector-go-ethereum-socketio/CA/" echo ">> copy_ethereum_validator_config() done." } @@ -33,6 +78,7 @@ function copy_sawtooth_validator_config() { echo ">> copy_sawtooth_validator_config()" cp -fr ${ROOT_DIR}/packages/cactus-plugin-ledger-connector-sawtooth-socketio/sample-config/* \ "${CONFIG_VOLUME_PATH}/connector-sawtooth-socketio/" + generate_certificate "SawtoothCactusValidator" "${CONFIG_VOLUME_PATH}/connector-sawtooth-socketio/CA/" echo ">> copy_sawtooth_validator_config() done." } diff --git a/packages-python/cactus_validator_socketio_indy/.gitignore b/packages-python/cactus_validator_socketio_indy/.gitignore index aca9962184..2d711bb5b4 100644 --- a/packages-python/cactus_validator_socketio_indy/.gitignore +++ b/packages-python/cactus_validator_socketio_indy/.gitignore @@ -1 +1,2 @@ -CactusValidatorSocketIOIndy.egg-info/ \ No newline at end of file +CactusValidatorSocketIOIndy.egg-info/ +testcli/connector.crt \ No newline at end of file diff --git a/packages-python/cactus_validator_socketio_indy/Dockerfile b/packages-python/cactus_validator_socketio_indy/Dockerfile index 07071c794d..b9da60ae4c 100644 --- a/packages-python/cactus_validator_socketio_indy/Dockerfile +++ b/packages-python/cactus_validator_socketio_indy/Dockerfile @@ -10,10 +10,10 @@ WORKDIR /home/indy COPY --chown=indy:indy './dist/CactusValidatorSocketIOIndy-0.0.1-py3-none-any.whl' '/home/indy' RUN pip3 install /home/indy/CactusValidatorSocketIOIndy-0.0.1-py3-none-any.whl -user root +USER root RUN python3 /home/indy/.local/lib/python3.8/site-packages/other/post_install_script.py -user indy +USER indy ARG pool_ip=172.16.0.2 ENV TEST_POOL_IP=$pool_ip diff --git a/packages-python/cactus_validator_socketio_indy/README.md b/packages-python/cactus_validator_socketio_indy/README.md index 9492b96bba..12c435d642 100644 --- a/packages-python/cactus_validator_socketio_indy/README.md +++ b/packages-python/cactus_validator_socketio_indy/README.md @@ -15,22 +15,25 @@ 1. Start indy testnet pool (follow instructions from `../../tools/docker/indy-testnet/` README). It should create docker network `indy-testnet_indy_net`, pool should be available at `172.16.0.2`. 1. Generate proof and store it in local `/etc/cactus`: ``` + rm -r /etc/cactus/validator_socketio_indy/* cd ../../examples/register-indy-data/ - ./script-build-docker.sh - docker run --rm -ti -v/etc/cactus/:/etc/cactus/ --net="host" register-indy-data --proof_only ``` 1. Copy indy validator config ``` - mkdir -p /etc/cactus/validator_socketio_indy/ - rm -r /etc/cactus/validator_socketio_indy/* cp -rf ./config/* /etc/cactus/validator_socketio_indy/ ``` -1. Copy default validator CA +1. Generate validator certificate using OpenSSL tool ``` - rm -r /etc/cactus/validator_socketio_indy/CA - cp -rf ./sample-CA/ /etc/cactus/validator_socketio_indy/CA + mkdir -p "/etc/cactus/validator_socketio_indy/CA/" + openssl ecparam -genkey -name "prime256v1" -out "/etc/cactus/validator_socketio_indy/CA/connector.priv" + openssl req -new -sha256 -key "/etc/cactus/validator_socketio_indy/CA/connector.priv" \ + -out "/etc/cactus/validator_socketio_indy/CA/connector.csr" \ + -subj "/C=JP/ST=Tokyo/L=Minato-Ku/O=CactusSamples/CN=IndyValidator" + openssl req -x509 -sha256 -days 365 -key "/etc/cactus/validator_socketio_indy/CA/connector.priv" \ + -in "/etc/cactus/validator_socketio_indy/CA/connector.csr" \ + -out "/etc/cactus/validator_socketio_indy/CA/connector.crt" ``` 1. Build and run validator container: ``` @@ -41,9 +44,8 @@ 1. Open separate console, install dependencies and run the testing script: ``` cd testcli/ - + ln -s /etc/cactus/validator_socketio_indy/CA/connector.crt . npm install - node testsock.js ``` diff --git a/packages-python/cactus_validator_socketio_indy/post_install_script.py b/packages-python/cactus_validator_socketio_indy/post_install_script.py index 171dfe73e3..8e9159a8c2 100644 --- a/packages-python/cactus_validator_socketio_indy/post_install_script.py +++ b/packages-python/cactus_validator_socketio_indy/post_install_script.py @@ -73,6 +73,7 @@ def __copy(source: str, destination: str) -> bool: # Copy supervisord.conf file if __copy(source=f'{SITE_PACKAGES}/other/supervisord.conf', destination='/etc'): print('supervisord file successfully copied') + # Copy utils.py if __copy(source=f'{UTILS_LOCATION}/utils.py', destination=f'{VALIDATOR_DST_DIR}/validator_socketio_module'): diff --git a/packages-python/cactus_validator_socketio_indy/sample-CA/connector.crt b/packages-python/cactus_validator_socketio_indy/sample-CA/connector.crt deleted file mode 100644 index 34773b65c3..0000000000 --- a/packages-python/cactus_validator_socketio_indy/sample-CA/connector.crt +++ /dev/null @@ -1,10 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIBdTCCARoCCQC/F+Mh551QzDAKBggqhkjOPQQDAjBCMQswCQYDVQQGEwJKUDEQ -MA4GA1UECAwHZXNqbXMxMjEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkg -THRkMB4XDTE4MDYyNzA3MjIzNVoXDTI4MDYyNDA3MjIzNVowQjELMAkGA1UEBhMC -SlAxEDAOBgNVBAgMB2Vzam1zMTIxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMg -UHR5IEx0ZDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABDPpSD2w0zrqJKraGD1b -5Jq2sDuacThSUqi7fvz8oyrWtuKDjZ15zIaSOtak6XRxFh9V9Gokdg5GNbW/pTZc -TuowCgYIKoZIzj0EAwIDSQAwRgIhAKH6ERsyd5bpEMIkY4clPqguwDWoTLk2VKq6 -ONEhUqotAiEA4yJxGmZpFdRScG2gDUIF2VDeX+XfHdJI2J41hyW9/zI= ------END CERTIFICATE----- diff --git a/packages-python/cactus_validator_socketio_indy/sample-CA/connector.priv b/packages-python/cactus_validator_socketio_indy/sample-CA/connector.priv deleted file mode 100644 index 6faf76a31e..0000000000 --- a/packages-python/cactus_validator_socketio_indy/sample-CA/connector.priv +++ /dev/null @@ -1,8 +0,0 @@ ------BEGIN EC PARAMETERS----- -BggqhkjOPQMBBw== ------END EC PARAMETERS----- ------BEGIN EC PRIVATE KEY----- -MHcCAQEEICIlCfK3zMTFzUgdaj01LAHjJmHlbg6Xql9+i70iPz5EoAoGCCqGSM49 -AwEHoUQDQgAEM+lIPbDTOuokqtoYPVvkmrawO5pxOFJSqLt+/PyjKta24oONnXnM -hpI61qTpdHEWH1X0aiR2DkY1tb+lNlxO6g== ------END EC PRIVATE KEY----- diff --git a/packages-python/cactus_validator_socketio_indy/testcli/connector.crt b/packages-python/cactus_validator_socketio_indy/testcli/connector.crt deleted file mode 120000 index 3f9db21635..0000000000 --- a/packages-python/cactus_validator_socketio_indy/testcli/connector.crt +++ /dev/null @@ -1 +0,0 @@ -../sample-CA/connector.crt \ No newline at end of file diff --git a/packages/cactus-api-client/src/main/typescript/socketio-api-client.ts b/packages/cactus-api-client/src/main/typescript/socketio-api-client.ts index f1dd571b9d..c2266b42de 100644 --- a/packages/cactus-api-client/src/main/typescript/socketio-api-client.ts +++ b/packages/cactus-api-client/src/main/typescript/socketio-api-client.ts @@ -36,7 +36,7 @@ export function verifyValidatorJwt( ): Promise { return new Promise((resolve, reject) => { const option: VerifyOptions = { - algorithms: ["ES256"], + algorithms: ["ES256", "ES384", "ES512", "RS256", "RS384", "RS512"], }; verify( diff --git a/packages/cactus-cmd-api-server/src/main/typescript/config/self-signed-pki-generator.ts b/packages/cactus-cmd-api-server/src/main/typescript/config/self-signed-pki-generator.ts index 1c15284f93..243fbbeb38 100644 --- a/packages/cactus-cmd-api-server/src/main/typescript/config/self-signed-pki-generator.ts +++ b/packages/cactus-cmd-api-server/src/main/typescript/config/self-signed-pki-generator.ts @@ -1,13 +1,31 @@ +/** + * @deprecated Moved to packages/cactus-test-tooling/src/main/typescript/pki/self-signed-pki-generator.ts + */ + import { pki, md } from "node-forge"; import { v4 as uuidV4 } from "uuid"; import { Strings } from "@hyperledger/cactus-common"; +/** + * @deprecated Moved to \@hyperledger/cactus-test-tooling + */ export type ForgeKeyPair = pki.rsa.KeyPair; +/** + * @deprecated Moved to \@hyperledger/cactus-test-tooling + */ export type ForgePrivateKey = pki.rsa.PrivateKey; +/** + * @deprecated Moved to \@hyperledger/cactus-test-tooling + */ export type ForgeCertificate = pki.Certificate; +/** + * @deprecated Moved to \@hyperledger/cactus-test-tooling + */ export type ForgeCertificateField = pki.CertificateField; /** + * @deprecated Moved to \@hyperledger/cactus-test-tooling + * * PKI as in public key infrastructure and x509 certificates. */ export interface IPki { @@ -18,6 +36,8 @@ export interface IPki { } /** + * @deprecated Moved to \@hyperledger/cactus-test-tooling + * * Do not use this for anything in a production deployment. It's meant as a helper * class for development and testing purposes (enhancing developer experience). * diff --git a/packages/cactus-plugin-ledger-connector-fabric-socketio/README.md b/packages/cactus-plugin-ledger-connector-fabric-socketio/README.md index 6ec774cf44..2b832b46f6 100644 --- a/packages/cactus-plugin-ledger-connector-fabric-socketio/README.md +++ b/packages/cactus-plugin-ledger-connector-fabric-socketio/README.md @@ -64,6 +64,10 @@ docker run -v/etc/cactus/:/etc/cactus -p 5040:5040 --net=fabric-all-in-one_testn npm run start ``` +## Configuration +- Validator can be configured in `/etc/cactus/connector-fabric-socketio/default.yaml` (see [sample-config](./sample-config/default.yaml) for details). +- This configuration can be overwriten in `NODE_CONFIG` environment variable (JSON format). See functional tests for example of that. + ## Usage samples - To confirm the operation of this package, please refer to the following business-logic sample application: - [cactus-example-discounted-asset-trade](../../examples/cactus-example-discounted-asset-trade) diff --git a/packages/cactus-plugin-ledger-connector-fabric-socketio/package.json b/packages/cactus-plugin-ledger-connector-fabric-socketio/package.json index 7579838a6f..a684a3c52e 100644 --- a/packages/cactus-plugin-ledger-connector-fabric-socketio/package.json +++ b/packages/cactus-plugin-ledger-connector-fabric-socketio/package.json @@ -20,6 +20,7 @@ "cookie-parser": "1.4.6", "debug": "4.1.1", "express": "4.17.3", + "fs-extra": "10.0.0", "fabric-ca-client": "1.4.19", "fabric-client": "1.4.19", "fabric-network": "1.4.19", @@ -34,6 +35,7 @@ }, "devDependencies": { "@hyperledger/cactus-api-client": "1.0.0", + "@hyperledger/cactus-test-tooling": "1.0.0", "@types/config": "0.0.41", "ts-node": "9.1.1" } diff --git a/packages/cactus-plugin-ledger-connector-fabric-socketio/sample-config/CA/connector.crt b/packages/cactus-plugin-ledger-connector-fabric-socketio/sample-config/CA/connector.crt deleted file mode 100644 index 34773b65c3..0000000000 --- a/packages/cactus-plugin-ledger-connector-fabric-socketio/sample-config/CA/connector.crt +++ /dev/null @@ -1,10 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIBdTCCARoCCQC/F+Mh551QzDAKBggqhkjOPQQDAjBCMQswCQYDVQQGEwJKUDEQ -MA4GA1UECAwHZXNqbXMxMjEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkg -THRkMB4XDTE4MDYyNzA3MjIzNVoXDTI4MDYyNDA3MjIzNVowQjELMAkGA1UEBhMC -SlAxEDAOBgNVBAgMB2Vzam1zMTIxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMg -UHR5IEx0ZDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABDPpSD2w0zrqJKraGD1b -5Jq2sDuacThSUqi7fvz8oyrWtuKDjZ15zIaSOtak6XRxFh9V9Gokdg5GNbW/pTZc -TuowCgYIKoZIzj0EAwIDSQAwRgIhAKH6ERsyd5bpEMIkY4clPqguwDWoTLk2VKq6 -ONEhUqotAiEA4yJxGmZpFdRScG2gDUIF2VDeX+XfHdJI2J41hyW9/zI= ------END CERTIFICATE----- diff --git a/packages/cactus-plugin-ledger-connector-fabric-socketio/sample-config/CA/connector.csr b/packages/cactus-plugin-ledger-connector-fabric-socketio/sample-config/CA/connector.csr deleted file mode 100644 index e828a1414b..0000000000 --- a/packages/cactus-plugin-ledger-connector-fabric-socketio/sample-config/CA/connector.csr +++ /dev/null @@ -1,8 +0,0 @@ ------BEGIN CERTIFICATE REQUEST----- -MIH9MIGkAgEAMEIxCzAJBgNVBAYTAkpQMRAwDgYDVQQIDAdlc2ptczEyMSEwHwYD -VQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjO -PQMBBwNCAAQz6Ug9sNM66iSq2hg9W+SatrA7mnE4UlKou378/KMq1rbig42decyG -kjrWpOl0cRYfVfRqJHYORjW1v6U2XE7qoAAwCgYIKoZIzj0EAwIDSAAwRQIgCUA1 -B5mZK7Hx79J1xBb0MGwuoUkt4bGPXbHqWEMZXQMCIQCRgadPkrNw56+pT5MVxA5K -vV6xTgmxUYrYnpkR4tptqQ== ------END CERTIFICATE REQUEST----- diff --git a/packages/cactus-plugin-ledger-connector-fabric-socketio/sample-config/CA/connector.priv b/packages/cactus-plugin-ledger-connector-fabric-socketio/sample-config/CA/connector.priv deleted file mode 100644 index 6faf76a31e..0000000000 --- a/packages/cactus-plugin-ledger-connector-fabric-socketio/sample-config/CA/connector.priv +++ /dev/null @@ -1,8 +0,0 @@ ------BEGIN EC PARAMETERS----- -BggqhkjOPQMBBw== ------END EC PARAMETERS----- ------BEGIN EC PRIVATE KEY----- -MHcCAQEEICIlCfK3zMTFzUgdaj01LAHjJmHlbg6Xql9+i70iPz5EoAoGCCqGSM49 -AwEHoUQDQgAEM+lIPbDTOuokqtoYPVvkmrawO5pxOFJSqLt+/PyjKta24oONnXnM -hpI61qTpdHEWH1X0aiR2DkY1tb+lNlxO6g== ------END EC PRIVATE KEY----- diff --git a/packages/cactus-plugin-ledger-connector-fabric-socketio/sample-config/default.yaml b/packages/cactus-plugin-ledger-connector-fabric-socketio/sample-config/default.yaml index c25933094c..e1c0a24e0a 100644 --- a/packages/cactus-plugin-ledger-connector-fabric-socketio/sample-config/default.yaml +++ b/packages/cactus-plugin-ledger-connector-fabric-socketio/sample-config/default.yaml @@ -1,8 +1,17 @@ sslParam: + # Port on which the validator will listen for requests. port: 5040 + # Private and public keys used by HTTPS server and to sign JWT messages. + # Must be either RSA or ECDSA. key: "/etc/cactus/connector-fabric-socketio/CA/connector.priv" cert: "/etc/cactus/connector-fabric-socketio/CA/connector.crt" + # JWT signing algorithm, must correspond to the private keys specified above. + # See more: https://www.rfc-editor.org/rfc/rfc7518#section-3.1 + # Default: ES256 (key must be ECDSA using P-256 and SHA-256) + # jwtAlgo: "ES256" +# log4js log level logLevel: "debug" +# Fabric ledger configuration fabric: mspid: "Org1MSP" keystore: "/etc/cactus/connector-fabric-socketio/wallet" diff --git a/packages/cactus-plugin-ledger-connector-fabric-socketio/src/main/typescript/connector/ValidatorAuthentication.ts b/packages/cactus-plugin-ledger-connector-fabric-socketio/src/main/typescript/connector/ValidatorAuthentication.ts index 5c33913a3a..c42f100e8a 100644 --- a/packages/cactus-plugin-ledger-connector-fabric-socketio/src/main/typescript/connector/ValidatorAuthentication.ts +++ b/packages/cactus-plugin-ledger-connector-fabric-socketio/src/main/typescript/connector/ValidatorAuthentication.ts @@ -5,9 +5,9 @@ * ValidatorAuthentication.ts */ -const fs = require("fs"); -const path = require("path"); -const jwt = require("jsonwebtoken"); +import fs from "fs"; +import crypto from "crypto"; +import jwt from "jsonwebtoken"; import * as config from "../common/core/config"; import { getLogger } from "log4js"; const logger = getLogger("ValidatorAuthentication[" + process.pid + "]"); @@ -25,12 +25,24 @@ export class ValidatorAuthentication { } } - const option = { - algorithm: "ES256", + const jwtAlgo = config.read('sslParam.jwtAlgo', 'ES256'); + const keyType = crypto.createPrivateKey(privateKey).asymmetricKeyType; + if (keyType === 'rsa' && jwtAlgo.startsWith('RS')) { + logger.debug(`Using RSA key with JWT algorithm ${jwtAlgo}`); + } + else if (keyType === 'ec' && jwtAlgo.startsWith('ES')) { + logger.debug(`Using ECDSA key with JWT algorithm ${jwtAlgo}`); + } + else { + throw new Error(`Not supported combination ${keyType}/${jwtAlgo}. Please use either RSA or ECDSA key.`); + } + + const option: jwt.SignOptions = { + algorithm: jwtAlgo, expiresIn: 60 * 15, // 15 minutes }; - const signature: string = jwt.sign(payload, privateKey, option); + const signature = jwt.sign(payload, privateKey, option); logger.debug(`signature: OK`); return signature; } diff --git a/packages/cactus-plugin-ledger-connector-fabric-socketio/src/test/typescript/integration/fabric-socketio-connector.test.ts b/packages/cactus-plugin-ledger-connector-fabric-socketio/src/test/typescript/integration/fabric-socketio-connector.test.ts index 3ebfc78956..5ab4906bee 100644 --- a/packages/cactus-plugin-ledger-connector-fabric-socketio/src/test/typescript/integration/fabric-socketio-connector.test.ts +++ b/packages/cactus-plugin-ledger-connector-fabric-socketio/src/test/typescript/integration/fabric-socketio-connector.test.ts @@ -24,6 +24,7 @@ const sutLogLevel: LogLevelDesc = "info"; import { FabricTestLedgerV1, pruneDockerAllIfGithubAction, + SelfSignedPkiGenerator, } from "@hyperledger/cactus-test-tooling"; import { @@ -52,17 +53,6 @@ const log: Logger = LoggerProvider.getOrCreate({ level: testLogLevel, }); -// Path to sample CA used by the test - creating new EC certs for each run is to verbose for our purpose -const sampleFabricCAPath = path.join( - process.cwd(), - "packages", - "cactus-plugin-ledger-connector-fabric-socketio", - "sample-config", - "CA", -); -const connectorCertPath = path.join(sampleFabricCAPath, "connector.crt"); -const connectorPrivKeyPath = path.join(sampleFabricCAPath, "connector.priv"); - /** * Main test suite */ @@ -91,6 +81,7 @@ describe("Fabric-SocketIO connector tests", () => { connectionProfile: Record, connectorCert: string, connectorPrivKey: string, + jwtAlgo: string, walletDir: string, adminName: string, adminSecret: string, @@ -108,6 +99,7 @@ describe("Fabric-SocketIO connector tests", () => { port: 0, // random port keyValue: connectorPrivKey, certValue: connectorCert, + jwtAlgo: jwtAlgo, }, logLevel: sutLogLevel, fabric: { @@ -119,7 +111,7 @@ describe("Fabric-SocketIO connector tests", () => { orderer: { name: connectionProfile.orderers[ordererId].grpcOptions[ - "ssl-target-name-override" + "ssl-target-name-override" ], url: connectionProfile.orderers[ordererId].url, tlscaValue: connectionProfile.orderers[ordererId].tlsCACerts.pem, @@ -193,9 +185,12 @@ describe("Fabric-SocketIO connector tests", () => { adminName, ); - // Read connector private key and certificate - connectorCertValue = fs.readFileSync(connectorCertPath, "ascii"); - connectorPrivKeyValue = fs.readFileSync(connectorPrivKeyPath, "ascii"); + // Generate connector private key and certificate + const pkiGenerator = new SelfSignedPkiGenerator(); + const pki = pkiGenerator.create("localhost"); + connectorCertValue = pki.certificatePem; + connectorPrivKeyValue = pki.privateKeyPem; + const jwtAlgo = "RS512"; // Get connector config log.info("Export connector config before loading the module..."); @@ -203,6 +198,7 @@ describe("Fabric-SocketIO connector tests", () => { connectionProfile, connectorCertValue, connectorPrivKeyValue, + jwtAlgo, tmpWalletDir, adminName, adminSecret, diff --git a/packages/cactus-plugin-ledger-connector-fabric-socketio/tsconfig.json b/packages/cactus-plugin-ledger-connector-fabric-socketio/tsconfig.json index 9a4e94797b..075e2dc343 100644 --- a/packages/cactus-plugin-ledger-connector-fabric-socketio/tsconfig.json +++ b/packages/cactus-plugin-ledger-connector-fabric-socketio/tsconfig.json @@ -15,6 +15,9 @@ "references": [ { "path": "../cactus-api-client/tsconfig.json" + }, + { + "path": "../cactus-test-tooling/tsconfig.json" } ] } diff --git a/packages/cactus-plugin-ledger-connector-go-ethereum-socketio/sample-config/CA/connector.crt b/packages/cactus-plugin-ledger-connector-go-ethereum-socketio/sample-config/CA/connector.crt deleted file mode 100644 index 34773b65c3..0000000000 --- a/packages/cactus-plugin-ledger-connector-go-ethereum-socketio/sample-config/CA/connector.crt +++ /dev/null @@ -1,10 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIBdTCCARoCCQC/F+Mh551QzDAKBggqhkjOPQQDAjBCMQswCQYDVQQGEwJKUDEQ -MA4GA1UECAwHZXNqbXMxMjEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkg -THRkMB4XDTE4MDYyNzA3MjIzNVoXDTI4MDYyNDA3MjIzNVowQjELMAkGA1UEBhMC -SlAxEDAOBgNVBAgMB2Vzam1zMTIxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMg -UHR5IEx0ZDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABDPpSD2w0zrqJKraGD1b -5Jq2sDuacThSUqi7fvz8oyrWtuKDjZ15zIaSOtak6XRxFh9V9Gokdg5GNbW/pTZc -TuowCgYIKoZIzj0EAwIDSQAwRgIhAKH6ERsyd5bpEMIkY4clPqguwDWoTLk2VKq6 -ONEhUqotAiEA4yJxGmZpFdRScG2gDUIF2VDeX+XfHdJI2J41hyW9/zI= ------END CERTIFICATE----- diff --git a/packages/cactus-plugin-ledger-connector-go-ethereum-socketio/sample-config/CA/connector.csr b/packages/cactus-plugin-ledger-connector-go-ethereum-socketio/sample-config/CA/connector.csr deleted file mode 100644 index e828a1414b..0000000000 --- a/packages/cactus-plugin-ledger-connector-go-ethereum-socketio/sample-config/CA/connector.csr +++ /dev/null @@ -1,8 +0,0 @@ ------BEGIN CERTIFICATE REQUEST----- -MIH9MIGkAgEAMEIxCzAJBgNVBAYTAkpQMRAwDgYDVQQIDAdlc2ptczEyMSEwHwYD -VQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjO -PQMBBwNCAAQz6Ug9sNM66iSq2hg9W+SatrA7mnE4UlKou378/KMq1rbig42decyG -kjrWpOl0cRYfVfRqJHYORjW1v6U2XE7qoAAwCgYIKoZIzj0EAwIDSAAwRQIgCUA1 -B5mZK7Hx79J1xBb0MGwuoUkt4bGPXbHqWEMZXQMCIQCRgadPkrNw56+pT5MVxA5K -vV6xTgmxUYrYnpkR4tptqQ== ------END CERTIFICATE REQUEST----- diff --git a/packages/cactus-plugin-ledger-connector-go-ethereum-socketio/sample-config/CA/connector.priv b/packages/cactus-plugin-ledger-connector-go-ethereum-socketio/sample-config/CA/connector.priv deleted file mode 100644 index 6faf76a31e..0000000000 --- a/packages/cactus-plugin-ledger-connector-go-ethereum-socketio/sample-config/CA/connector.priv +++ /dev/null @@ -1,8 +0,0 @@ ------BEGIN EC PARAMETERS----- -BggqhkjOPQMBBw== ------END EC PARAMETERS----- ------BEGIN EC PRIVATE KEY----- -MHcCAQEEICIlCfK3zMTFzUgdaj01LAHjJmHlbg6Xql9+i70iPz5EoAoGCCqGSM49 -AwEHoUQDQgAEM+lIPbDTOuokqtoYPVvkmrawO5pxOFJSqLt+/PyjKta24oONnXnM -hpI61qTpdHEWH1X0aiR2DkY1tb+lNlxO6g== ------END EC PRIVATE KEY----- diff --git a/packages/cactus-plugin-ledger-connector-sawtooth-socketio/sample-config/CA/connector.crt b/packages/cactus-plugin-ledger-connector-sawtooth-socketio/sample-config/CA/connector.crt deleted file mode 100644 index 34773b65c3..0000000000 --- a/packages/cactus-plugin-ledger-connector-sawtooth-socketio/sample-config/CA/connector.crt +++ /dev/null @@ -1,10 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIBdTCCARoCCQC/F+Mh551QzDAKBggqhkjOPQQDAjBCMQswCQYDVQQGEwJKUDEQ -MA4GA1UECAwHZXNqbXMxMjEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkg -THRkMB4XDTE4MDYyNzA3MjIzNVoXDTI4MDYyNDA3MjIzNVowQjELMAkGA1UEBhMC -SlAxEDAOBgNVBAgMB2Vzam1zMTIxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMg -UHR5IEx0ZDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABDPpSD2w0zrqJKraGD1b -5Jq2sDuacThSUqi7fvz8oyrWtuKDjZ15zIaSOtak6XRxFh9V9Gokdg5GNbW/pTZc -TuowCgYIKoZIzj0EAwIDSQAwRgIhAKH6ERsyd5bpEMIkY4clPqguwDWoTLk2VKq6 -ONEhUqotAiEA4yJxGmZpFdRScG2gDUIF2VDeX+XfHdJI2J41hyW9/zI= ------END CERTIFICATE----- diff --git a/packages/cactus-plugin-ledger-connector-sawtooth-socketio/sample-config/CA/connector.csr b/packages/cactus-plugin-ledger-connector-sawtooth-socketio/sample-config/CA/connector.csr deleted file mode 100644 index e828a1414b..0000000000 --- a/packages/cactus-plugin-ledger-connector-sawtooth-socketio/sample-config/CA/connector.csr +++ /dev/null @@ -1,8 +0,0 @@ ------BEGIN CERTIFICATE REQUEST----- -MIH9MIGkAgEAMEIxCzAJBgNVBAYTAkpQMRAwDgYDVQQIDAdlc2ptczEyMSEwHwYD -VQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjO -PQMBBwNCAAQz6Ug9sNM66iSq2hg9W+SatrA7mnE4UlKou378/KMq1rbig42decyG -kjrWpOl0cRYfVfRqJHYORjW1v6U2XE7qoAAwCgYIKoZIzj0EAwIDSAAwRQIgCUA1 -B5mZK7Hx79J1xBb0MGwuoUkt4bGPXbHqWEMZXQMCIQCRgadPkrNw56+pT5MVxA5K -vV6xTgmxUYrYnpkR4tptqQ== ------END CERTIFICATE REQUEST----- diff --git a/packages/cactus-plugin-ledger-connector-sawtooth-socketio/sample-config/CA/connector.priv b/packages/cactus-plugin-ledger-connector-sawtooth-socketio/sample-config/CA/connector.priv deleted file mode 100644 index 6faf76a31e..0000000000 --- a/packages/cactus-plugin-ledger-connector-sawtooth-socketio/sample-config/CA/connector.priv +++ /dev/null @@ -1,8 +0,0 @@ ------BEGIN EC PARAMETERS----- -BggqhkjOPQMBBw== ------END EC PARAMETERS----- ------BEGIN EC PRIVATE KEY----- -MHcCAQEEICIlCfK3zMTFzUgdaj01LAHjJmHlbg6Xql9+i70iPz5EoAoGCCqGSM49 -AwEHoUQDQgAEM+lIPbDTOuokqtoYPVvkmrawO5pxOFJSqLt+/PyjKta24oONnXnM -hpI61qTpdHEWH1X0aiR2DkY1tb+lNlxO6g== ------END EC PRIVATE KEY----- diff --git a/packages/cactus-test-tooling/package.json b/packages/cactus-test-tooling/package.json index 55cf01ecd5..e3088c423f 100644 --- a/packages/cactus-test-tooling/package.json +++ b/packages/cactus-test-tooling/package.json @@ -76,13 +76,15 @@ "keycloak-admin": "1.14.21", "lodash": "4.17.21", "node-ssh": "12.0.0", + "node-forge": "1.3.0", "p-retry": "4.6.1", "run-time-error": "1.4.0", "tar-stream": "2.2.0", "temp": "0.9.4", "typescript-optional": "2.0.1", "web3": "1.5.2", - "web3-core": "1.5.2" + "web3-core": "1.5.2", + "uuid": "8.3.2" }, "devDependencies": { "@types/dockerode": "3.2.7", diff --git a/packages/cactus-test-tooling/src/main/typescript/pki/self-signed-pki-generator.ts b/packages/cactus-test-tooling/src/main/typescript/pki/self-signed-pki-generator.ts new file mode 100644 index 0000000000..1c15284f93 --- /dev/null +++ b/packages/cactus-test-tooling/src/main/typescript/pki/self-signed-pki-generator.ts @@ -0,0 +1,155 @@ +import { pki, md } from "node-forge"; +import { v4 as uuidV4 } from "uuid"; +import { Strings } from "@hyperledger/cactus-common"; + +export type ForgeKeyPair = pki.rsa.KeyPair; +export type ForgePrivateKey = pki.rsa.PrivateKey; +export type ForgeCertificate = pki.Certificate; +export type ForgeCertificateField = pki.CertificateField; + +/** + * PKI as in public key infrastructure and x509 certificates. + */ +export interface IPki { + keyPair: ForgeKeyPair; + certificate: ForgeCertificate; + certificatePem: string; + privateKeyPem: string; +} + +/** + * Do not use this for anything in a production deployment. It's meant as a helper + * class for development and testing purposes (enhancing developer experience). + * + * Secure by default is one of our core design principles and it's much harder to + * enforce/implement that it sounds when you also do not want to ruin the ease + * of use of the software. Dynamically pre-provisioning PKI is notoriously + * complicated and error prone to the average user/developer. + * + */ +export class SelfSignedPkiGenerator { + public create(commonName: string, parent?: IPki): IPki { + const keyPair: pki.rsa.KeyPair = pki.rsa.generateKeyPair(4096); + const privateKeyPem: string = pki.privateKeyToPem(keyPair.privateKey); + const certificate = pki.createCertificate(); + + this.configureCertificateParameters(keyPair, certificate, commonName); + if (parent) { + certificate.setIssuer(parent.certificate.subject.attributes); + certificate.publicKey = keyPair.publicKey; + // certificate.privateKey = keyPair.privateKey; + certificate.sign(parent.keyPair.privateKey, md.sha512.create()); + + if (!parent.certificate.verify(certificate)) { + throw new Error("Could not verify newly generated certificate"); + } + } else { + certificate.sign(keyPair.privateKey, md.sha512.create()); + } + + const certificatePem = pki.certificateToPem(certificate); + return { keyPair, certificate, certificatePem, privateKeyPem }; + } + + public configureCertificateParameters( + keyPair: pki.rsa.KeyPair, + certificate: pki.Certificate, + commonName: string, + ): pki.Certificate { + // 20 octets max for serial numbers of certs as per the standard + const serialNumber = Strings.replaceAll(uuidV4(), "-", "").substring(0, 19); + certificate.serialNumber = serialNumber; + certificate.publicKey = keyPair.publicKey; + certificate.privateKey = keyPair.privateKey; + certificate.validity.notBefore = new Date(); + certificate.validity.notAfter = new Date(); + + const nextYear = certificate.validity.notBefore.getFullYear() + 1; + certificate.validity.notAfter.setFullYear(nextYear); + + const certificateFields: ForgeCertificateField[] = [ + { + shortName: "CN", + name: "commonName", + value: commonName, + }, + { + name: "countryName", + value: "Universe", + }, + { + shortName: "ST", + value: "Milky Way", + }, + { + shortName: "L", + name: "localityName", + value: "Planet Earth", + }, + { + shortName: "O", + name: "organizationName", + value: "Hyperledger", + }, + { + shortName: "OU", + value: "Cactus", + }, + { + name: "unstructuredName", + value: "Cactus Dummy Self Signed Certificates", + }, + ]; + + certificate.setSubject(certificateFields); + + certificate.setIssuer(certificateFields); + + certificate.setExtensions([ + { + name: "basicConstraints", + cA: true, + }, + { + name: "keyUsage", + keyCertSign: true, + digitalSignature: true, + nonRepudiation: true, + keyEncipherment: true, + dataEncipherment: true, + }, + { + name: "extKeyUsage", + serverAuth: true, + clientAuth: true, + codeSigning: true, + emailProtection: true, + timeStamping: true, + }, + { + name: "nsCertType", + client: true, + server: true, + email: true, + objsign: true, + sslCA: true, + emailCA: true, + objCA: true, + }, + { + name: "subjectAltName", + altNames: [ + { + type: 7, // IP + ip: "127.0.0.1", + }, + ], + }, + { + name: "subjectKeyIdentifier", + }, + ]); + + return certificate; + } +} diff --git a/packages/cactus-test-tooling/src/main/typescript/public-api.ts b/packages/cactus-test-tooling/src/main/typescript/public-api.ts index 9057b39cab..055b3597b2 100755 --- a/packages/cactus-test-tooling/src/main/typescript/public-api.ts +++ b/packages/cactus-test-tooling/src/main/typescript/public-api.ts @@ -129,6 +129,15 @@ export { OpenEthereumTestLedger, } from "./openethereum/openethereum-test-ledger"; +export { + SelfSignedPkiGenerator, + ForgeCertificateField, + ForgeCertificate, + ForgeKeyPair, + ForgePrivateKey, + IPki, +} from "./pki/self-signed-pki-generator"; + export { GoIpfsTestContainer, IGoIpfsTestContainerOptions,