diff --git a/.github/workflows/kra-ecc-test.yml b/.github/workflows/kra-ecc-test.yml new file mode 100644 index 00000000000..a9b4fc6a250 --- /dev/null +++ b/.github/workflows/kra-ecc-test.yml @@ -0,0 +1,389 @@ +name: KRA with ECC +# docs/installation/kra/Installing_KRA_with_ECC.md + +on: workflow_call + +env: + DB_IMAGE: ${{ vars.DB_IMAGE || 'quay.io/389ds/dirsrv' }} + +jobs: + test: + name: Test + runs-on: ubuntu-latest + env: + SHARED: /tmp/workdir/pki + steps: + - name: Clone repository + uses: actions/checkout@v3 + + - name: Retrieve PKI images + uses: actions/cache@v3 + with: + key: pki-images-${{ github.sha }} + path: pki-images.tar + + - name: Load PKI images + run: docker load --input pki-images.tar + + - name: Create network + run: docker network create example + + - name: Set up DS container + run: | + tests/bin/ds-container-create.sh ds + env: + IMAGE: ${{ env.DB_IMAGE }} + HOSTNAME: ds.example.com + PASSWORD: Secret.123 + + - name: Connect DS container to network + run: docker network connect example ds --alias ds.example.com + + - name: Set up PKI container + run: | + tests/bin/runner-init.sh pki + env: + HOSTNAME: pki.example.com + + - name: Connect PKI container to network + run: docker network connect example pki --alias pki.example.com + + - name: Install CA + run: | + docker exec pki pkispawn \ + -f /usr/share/pki/server/examples/installation/ca-ecc.cfg \ + -s CA \ + -D pki_ds_url=ldap://ds.example.com:3389 \ + -v + + - name: Install KRA + run: | + docker exec pki pkispawn \ + -f /usr/share/pki/server/examples/installation/kra-ecc.cfg \ + -s KRA \ + -D pki_ds_url=ldap://ds.example.com:3389 \ + -v + + - name: Check KRA storage cert + run: | + docker exec pki pki-server cert-export kra_storage \ + --cert-file kra_storage.crt + docker exec pki openssl req -text -noout \ + -in /etc/pki/pki-tomcat/certs/kra_storage.csr + docker exec pki openssl x509 -text -noout -in kra_storage.crt | tee output + + # public key algorithm should be "rsaEncryption" + echo "rsaEncryption" > expected + sed -n -e "s/\s*$//" -e "s/^\s*Public Key Algorithm:\s*\(.*\)$/\1/p" output > actual + diff expected actual + + # signing algorithm should be "ecdsa-with-SHA512" + echo "ecdsa-with-SHA512" > expected + sed -n -e "s/\s*$//" -e "s/^\s*Signature Algorithm:\s*\(.*\)$/\1/p" output | uniq > actual + diff expected actual + + # default signing algorithm should not exist + echo "ERROR: No such parameter: kra.storage.defaultSigningAlgorithm" > expected + docker exec pki pki-server kra-config-show kra.storage.defaultSigningAlgorithm \ + > >(tee stdout) 2> >(tee stderr >&2) || true + diff expected stderr + + - name: Check KRA transport cert + run: | + docker exec pki pki-server cert-export kra_transport \ + --cert-file kra_transport.crt + docker exec pki openssl req -text -noout \ + -in /etc/pki/pki-tomcat/certs/kra_transport.csr + docker exec pki openssl x509 -text -noout -in kra_transport.crt | tee output + + # public key algorithm should be "rsaEncryption" + echo "rsaEncryption" > expected + sed -n -e "s/\s*$//" -e "s/^\s*Public Key Algorithm:\s*\(.*\)$/\1/p" output > actual + diff expected actual + + # signing algorithm should be "ecdsa-with-SHA512" + echo "ecdsa-with-SHA512" > expected + sed -n -e "s/\s*$//" -e "s/^\s*Signature Algorithm:\s*\(.*\)$/\1/p" output | uniq > actual + diff expected actual + + # default signing algorithm should not exist + echo "ERROR: No such parameter: kra.transport.defaultSigningAlgorithm" > expected + docker exec pki pki-server kra-config-show kra.transport.defaultSigningAlgorithm \ + > >(tee stdout) 2> >(tee stderr >&2) || true + diff expected stderr + + - name: Check KRA audit signing cert + run: | + docker exec pki pki-server cert-export kra_audit_signing \ + --cert-file kra_audit_signing.crt + docker exec pki openssl req -text -noout \ + -in /etc/pki/pki-tomcat/certs/kra_audit_signing.csr + docker exec pki openssl x509 -text -noout -in kra_audit_signing.crt | tee output + + # public key algorithm should be "id-ecPublicKey" + echo "id-ecPublicKey" > expected + sed -n -e "s/\s*$//" -e "s/^\s*Public Key Algorithm:\s*\(.*\)$/\1/p" output > actual + diff expected actual + + # signing algorithm should be "ecdsa-with-SHA512" + echo "ecdsa-with-SHA512" > expected + sed -n -e "s/\s*$//" -e "s/^\s*Signature Algorithm:\s*\(.*\)$/\1/p" output | uniq > actual + diff expected actual + + # default signing algorithm should be "SHA384withEC" + echo "SHA384withEC" > expected + docker exec pki pki-server kra-config-show kra.audit_signing.defaultSigningAlgorithm | tee actual + diff expected actual + + - name: Check subsystem cert + run: | + docker exec pki pki-server cert-export subsystem \ + --cert-file subsystem.crt + docker exec pki openssl req -text -noout \ + -in /etc/pki/pki-tomcat/certs/subsystem.csr + docker exec pki openssl x509 -text -noout -in subsystem.crt | tee output + + # public key algorithm should be "id-ecPublicKey" + echo "id-ecPublicKey" > expected + sed -n -e "s/\s*$//" -e "s/^\s*Public Key Algorithm:\s*\(.*\)$/\1/p" output > actual + diff expected actual + + # signing algorithm should be "ecdsa-with-SHA512" + echo "ecdsa-with-SHA512" > expected + sed -n -e "s/\s*$//" -e "s/^\s*Signature Algorithm:\s*\(.*\)$/\1/p" output | uniq > actual + diff expected actual + + # default signing algorithm should not exist + echo "ERROR: No such parameter: kra.subsystem.defaultSigningAlgorithm" > expected + docker exec pki pki-server kra-config-show kra.subsystem.defaultSigningAlgorithm \ + > >(tee stdout) 2> >(tee stderr >&2) || true + diff expected stderr + + - name: Check SSL server cert + run: | + docker exec pki pki-server cert-export sslserver \ + --cert-file sslserver.crt + docker exec pki openssl req -text -noout \ + -in /etc/pki/pki-tomcat/certs/sslserver.csr + docker exec pki openssl x509 -text -noout -in sslserver.crt | tee output + + # public key algorithm should be "id-ecPublicKey" + echo "id-ecPublicKey" > expected + sed -n -e "s/\s*$//" -e "s/^\s*Public Key Algorithm:\s*\(.*\)$/\1/p" output > actual + diff expected actual + + # signing algorithm should be "ecdsa-with-SHA512" + echo "ecdsa-with-SHA512" > expected + sed -n -e "s/\s*$//" -e "s/^\s*Signature Algorithm:\s*\(.*\)$/\1/p" output | uniq > actual + diff expected actual + + # default signing algorithm should not exist + echo "ERROR: No such parameter: kra.sslserver.defaultSigningAlgorithm" > expected + docker exec pki pki-server kra-config-show kra.sslserver.defaultSigningAlgorithm \ + > >(tee stdout) 2> >(tee stderr >&2) || true + diff expected stderr + + - name: Check KRA admin cert + run: | + docker exec pki openssl x509 -text -noout \ + -in /root/.dogtag/pki-tomcat/ca_admin.cert | tee output + + # public key algorithm should be "id-ecPublicKey" + echo "id-ecPublicKey" > expected + sed -n -e "s/\s*$//" -e "s/^\s*Public Key Algorithm:\s*\(.*\)$/\1/p" output > actual + diff expected actual + + # signing algorithm should be "ecdsa-with-SHA512" + echo "ecdsa-with-SHA512" > expected + sed -n -e "s/\s*$//" -e "s/^\s*Signature Algorithm:\s*\(.*\)$/\1/p" output | uniq > actual + diff expected actual + + - name: Run PKI healthcheck + run: docker exec pki pki-healthcheck --failures-only + + - name: Verify KRA admin + run: | + docker exec pki pki-server cert-export ca_signing --cert-file ca_signing.crt + docker exec pki pki client-cert-import ca_signing --ca-cert ca_signing.crt + docker exec pki pki pkcs12-import \ + --pkcs12 /root/.dogtag/pki-tomcat/ca_admin_cert.p12 \ + --pkcs12-password Secret.123 + docker exec pki pki -n caadmin kra-user-show kraadmin + + - name: Enable caECUserCert profile + run: | + docker exec pki pki-server ca-profile-mod --enable true caECUserCert + docker exec pki pki-server restart --wait + + - name: Verify key archival with CRMFPopClient + run: | + # generate key and cert request + docker exec pki CRMFPopClient \ + -d /root/.dogtag/nssdb \ + -p "" \ + -m pki.example.com:8080 \ + -f caECUserCert \ + -a ec \ + -t false \ + -n UID=testuser1 \ + -u testuser1 \ + -r testuser1 \ + -b kra_transport.crt | tee output + + REQUEST_ID=$(sed -n "s/^\s*Request ID:\s*\(\S*\)\s*$/\1/p" output) + echo "Request ID: $REQUEST_ID" + + # issue cert + docker exec pki pki \ + -u caadmin \ + -w Secret.123 \ + ca-cert-request-approve \ + --force \ + $REQUEST_ID | tee output + + CERT_ID=$(sed -n "s/^\s*Certificate ID:\s*\(\S*\)\s*$/\1/p" output) + echo "Cert ID: $CERT_ID" + + # import cert + docker exec pki pki ca-cert-export --output-file testuser1.crt $CERT_ID + docker exec pki pki nss-cert-import --cert testuser1.crt testuser1 + docker exec pki pki nss-cert-show testuser1 | tee output + + # verify that the cert matches the key (trust flags must be u,u,u) + sed -n "s/^\s*Trust Flags:\s*\(\S*\)\s*$/\1/p" output > actual + echo "u,u,u" > expected + diff expected actual + + docker exec pki pki \ + -u kraadmin \ + -w Secret.123 \ + kra-key-find --owner UID=testuser1 | tee output + + HEX_KEY_ID=$(sed -n "s/^\s*Key ID:\s*\(\S*\)$/\1/p" output) + echo "Key ID: $HEX_KEY_ID" + + DEC_KEY_ID=$(python -c "print(int('$HEX_KEY_ID', 16))") + echo "Dec Key ID: $DEC_KEY_ID" + + # get key record + docker exec pki ldapsearch \ + -H ldap://ds.example.com:3389 \ + -x \ + -D "cn=Directory Manager" \ + -w Secret.123 \ + -b "cn=$DEC_KEY_ID,ou=keyRepository,ou=kra,dc=kra,dc=pki,dc=example,dc=com" \ + -o ldif_wrap=no \ + -LLL | tee output + + # encryption mode should be "false" by default + echo "false" > expected + sed -n 's/^metaInfo: payloadEncrypted:\(.*\)$/\1/p' output > actual + diff expected actual + + # key wrap algorithm should be "AES KeyWrap/Padding" by default + echo "AES KeyWrap/Padding" > expected + sed -n 's/^metaInfo: payloadWrapAlgorithm:\(.*\)$/\1/p' output > actual + diff expected actual + + - name: Verify key archival with pki client-cert-request + run: | + # generate key and cert request + docker exec pki pki \ + -U http://pki.example.com:8080 \ + client-cert-request \ + --profile caECUserCert \ + --type crmf \ + --algorithm ec \ + --permanent \ + --transport kra_transport.crt \ + UID=testuser2 | tee output + + REQUEST_ID=$(sed -n "s/^\s*Request ID:\s*\(\S*\)\s*$/\1/p" output) + echo "Request ID: $REQUEST_ID" + + # issue cert + docker exec pki pki \ + -u caadmin \ + -w Secret.123 \ + ca-cert-request-approve \ + --force \ + $REQUEST_ID | tee output + + CERT_ID=$(sed -n "s/^\s*Certificate ID:\s*\(\S*\)\s*$/\1/p" output) + echo "Cert ID: $CERT_ID" + + # import cert + docker exec pki pki ca-cert-export --output-file testuser2.crt $CERT_ID + docker exec pki pki nss-cert-import --cert testuser2.crt testuser2 + docker exec pki pki nss-cert-show testuser2 | tee output + + # verify that the cert matches the key (trust flags must be u,u,u) + sed -n "s/^\s*Trust Flags:\s*\(\S*\)\s*$/\1/p" output > actual + echo "u,u,u" > expected + diff expected actual + + docker exec pki pki \ + -u kraadmin \ + -w Secret.123 \ + kra-key-find --owner UID=testuser2 | tee output + + HEX_KEY_ID=$(sed -n "s/^\s*Key ID:\s*\(\S*\)$/\1/p" output) + echo "Key ID: $HEX_KEY_ID" + + DEC_KEY_ID=$(python -c "print(int('$HEX_KEY_ID', 16))") + echo "Dec Key ID: $DEC_KEY_ID" + + # get key record + docker exec pki ldapsearch \ + -H ldap://ds.example.com:3389 \ + -x \ + -D "cn=Directory Manager" \ + -w Secret.123 \ + -b "cn=$DEC_KEY_ID,ou=keyRepository,ou=kra,dc=kra,dc=pki,dc=example,dc=com" \ + -o ldif_wrap=no \ + -LLL | tee output + + # encryption mode should be "false" by default + echo "false" > expected + sed -n 's/^metaInfo: payloadEncrypted:\(.*\)$/\1/p' output > actual + diff expected actual + + # key wrap algorithm should be "AES KeyWrap/Padding" by default + echo "AES KeyWrap/Padding" > expected + sed -n 's/^metaInfo: payloadWrapAlgorithm:\(.*\)$/\1/p' output > actual + diff expected actual + + - name: Check PKI server systemd journal + if: always() + run: | + docker exec pki journalctl -x --no-pager -u pki-tomcatd@pki-tomcat.service + + - name: Check CA debug log + if: always() + run: | + docker exec pki find /var/log/pki/pki-tomcat/ca -name "debug.*" -exec cat {} \; + + - name: Check KRA debug log + if: always() + run: | + docker exec pki find /var/log/pki/pki-tomcat/kra -name "debug.*" -exec cat {} \; + + - name: Gather artifacts + if: always() + run: | + tests/bin/ds-artifacts-save.sh ds + tests/bin/pki-artifacts-save.sh pki + continue-on-error: true + + - name: Remove KRA + run: docker exec pki pkidestroy -i pki-tomcat -s KRA -v + + - name: Remove CA + run: docker exec pki pkidestroy -i pki-tomcat -s CA -v + + - name: Upload artifacts + if: always() + uses: actions/upload-artifact@v3 + with: + name: kra-ecc + path: /tmp/artifacts diff --git a/.github/workflows/kra-tests.yml b/.github/workflows/kra-tests.yml index 1eb6af066a8..3ac6c119966 100644 --- a/.github/workflows/kra-tests.yml +++ b/.github/workflows/kra-tests.yml @@ -18,6 +18,11 @@ jobs: needs: build uses: ./.github/workflows/kra-oaep-test.yml + kra-ecc-test: + name: KRA with ECC + needs: build + uses: ./.github/workflows/kra-ecc-test.yml + kra-separate-test: name: KRA on separate instance needs: build diff --git a/base/server/examples/installation/kra-ecc.cfg b/base/server/examples/installation/kra-ecc.cfg new file mode 100644 index 00000000000..bf35ceabeac --- /dev/null +++ b/base/server/examples/installation/kra-ecc.cfg @@ -0,0 +1,50 @@ +[DEFAULT] +pki_server_database_password=Secret.123 + +[KRA] +pki_admin_email=kraadmin@example.com +pki_admin_name=kraadmin +pki_admin_nickname=kraadmin +pki_admin_password=Secret.123 +pki_admin_uid=kraadmin +pki_admin_key_type=ecc +pki_admin_key_size=nistp521 +pki_admin_key_algorithm=SHA384withEC + +pki_client_pkcs12_password=Secret.123 + +pki_ds_base_dn=dc=kra,dc=pki,dc=example,dc=com +pki_ds_database=kra +pki_ds_password=Secret.123 + +pki_security_domain_name=EXAMPLE +pki_security_domain_user=caadmin +pki_security_domain_password=Secret.123 + +pki_storage_nickname=kra_storage +pki_storage_key_type=rsa +pki_storage_key_algorithm=SHA384withRSA +pki_storage_key_size=2048 +pki_storage_signing_algorithm=SHA384withRSA + +pki_transport_nickname=kra_transport +pki_transport_key_type=rsa +pki_transport_key_algorithm=SHA384withRSA +pki_transport_key_size=2048 +pki_transport_signing_algorithm=SHA384withRSA + +pki_audit_signing_nickname=kra_audit_signing +pki_audit_signing_key_type=ecc +pki_audit_signing_key_algorithm=SHA384withEC +pki_audit_signing_key_size=nistp521 +pki_audit_signing_signing_algorithm=SHA384withEC + +pki_sslserver_nickname=sslserver +pki_sslserver_key_type=ecc +pki_sslserver_key_algorithm=SHA384withEC +pki_sslserver_key_size=nistp521 + +pki_subsystem_nickname=subsystem +pki_subsystem_key_type=ecc +pki_subsystem_key_algorithm=SHA384withEC +pki_subsystem_key_size=nistp521