Skip to content

Commit

Permalink
Add test for CA password policy enforcement
Browse files Browse the repository at this point in the history
  • Loading branch information
fmarco76 committed Feb 10, 2025
1 parent 72aaadf commit eddc530
Show file tree
Hide file tree
Showing 5 changed files with 184 additions and 9 deletions.
143 changes: 143 additions & 0 deletions .github/workflows/ca-password-enforcement-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
name: CA password enforcement

on: workflow_call

env:
DS_IMAGE: ${{ vars.DS_IMAGE || 'quay.io/389ds/dirsrv' }}

jobs:
# docs/installation/kra/Installing_KRA.md
test:
name: Test
runs-on: ubuntu-latest
env:
SHARED: /tmp/workdir/pki
steps:
- name: Clone repository
uses: actions/checkout@v4

- name: Retrieve PKI images
uses: actions/cache@v4
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-create.sh \
--image=${{ env.DS_IMAGE }} \
--hostname=ds.example.com \
--password=Secret.123 \
ds
- 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.cfg \
-s CA \
-D pki_ds_url=ldap://ds.example.com:3389 \
-v
docker exec pki pki-server cert-find
- name: Install KRA
run: |
docker exec pki pkispawn \
-f /usr/share/pki/server/examples/installation/kra.cfg \
-s KRA \
-D pki_ds_url=ldap://ds.example.com:3389 \
-v
- name: Get CA signing certificate
run: |
docker exec pki pki-server cert-export ca_signing --cert-file ca_signing.crt
- name: Request profile
run: |
docker exec pki dnf install -y jq
docker exec pki curl --cacert ca_signing.crt -o req.json https://pki.example.com:8443/ca/rest/certrequests/profiles/caServerKeygen_UserCert
docker exec pki jq '.Input[0].Attribute[1].Value|="RSA" | .Input[0].Attribute[2].Value|="2048" | .Input[1].Attribute[0].Value|="test1"' req.json >req.json
- name: Submit request with good password
run: |
jq '.Input[0].Attribute[0].Value|="k342r09cmIJmklOLIJ,lwerkln234lik-[df"' req.json | \
docker exec -i pki curl --cacert ca_signing.crt --json @- -o output https://pki.example.com:8443/ca/rest/certrequests
echo '"pending"' > expected
docker exec pki jq '.entries[0].requestStatus' output > actual
diff expected actual
- name: Submit request with short password
run: |
jq '.Input[0].Attribute[0].Value|="k342r0"' req.json | \
docker exec -i pki curl --cacert ca_signing.crt --json @- -o output https://pki.example.com:8443/ca/rest/certrequests
cat > expected <<EOF
"rejected"
"The password must be at least 20 characters"
EOF
docker exec pki jq '.entries[0].requestStatus, .entries[0].errorMessage' output > actual
diff expected actual
- name: Submit request with numberic password
run: |
jq '.Input[0].Attribute[0].Value|="1234567890246801357938"' req.json | \
docker exec -i pki curl --cacert ca_signing.crt --json @- -o output https://pki.example.com:8443/ca/rest/certrequests
cat > expected <<EOF
"rejected"
"The password requires at least 2 upper case letter(s)"
EOF
docker exec pki jq '.entries[0].requestStatus, .entries[0].errorMessage' output > actual
diff expected actual
- name: Disable password policy
run: |
docker exec pki sed -i \
's/^policyset.userCertSet.list=1,10,2,3,4,5,6,7,8,9,11/policyset.userCertSet.list=1,10,2,3,4,5,6,7,8,9/' \
/etc/pki/pki-tomcat/ca/profiles/ca/caServerKeygen_UserCert.cfg
docker exec pki pki-server ca redeploy --wait
- name: Submit request with minimal password
run: |
jq '.Input[0].Attribute[0].Value|="1"' req.json | \
docker exec -i pki curl --cacert ca_signing.crt --json @- -o output https://pki.example.com:8443/ca/rest/certrequests
echo '"pending"' > expected
docker exec pki jq '.entries[0].requestStatus' output > actual
diff expected actual
- name: Remove KRA
run: docker exec pki pkidestroy -s KRA -v

- name: Remove CA
run: docker exec pki pkidestroy -s CA -v

- name: Check CA debug log
if: always()
run: |
docker exec pki find /var/lib/pki/pki-tomcat/logs/ca -name "debug.*" -exec cat {} \;
- name: Check KRA debug log
if: always()
run: |
docker exec pki find /var/lib/pki/pki-tomcat/logs/kra -name "debug.*" -exec cat {} \;
5 changes: 5 additions & 0 deletions .github/workflows/ca-tests2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ jobs:
needs: build
uses: ./.github/workflows/ca-nuxwdog-test.yml

ca-password-enforcment-test:
name: CA password enforcement
needs: build
uses: ./.github/workflows/ca-password-enforcement-test.yml

scep-test:
name: SCEP responder
needs: build
Expand Down
4 changes: 2 additions & 2 deletions base/server/src/main/resources/UserMessages.properties
Original file line number Diff line number Diff line change
Expand Up @@ -577,9 +577,9 @@ CMS_PASSWORD_INVALID_LEN=The password must be at least {0} characters
CMS_PASSWORD_INVALID_LEN_1=The password must be at least {0} characters
CMS_PASSWORD_NON_ALPHANUMERIC=The password contains non-alphanumeric characters
CMS_PASSWORD_MISSING_PUNCTUATION=The password requires at least {0} punctuation symbol(s)
CMS_PASSWORD_MISSING_NUMERIC=The password requires at least {0} numeric digit(s), excluding digits in the final position
CMS_PASSWORD_MISSING_NUMERIC=The password requires at least {0} numeric digit(s)
CMS_PASSWORD_MISSING_NUMERIC_1=The password requires at least {0} numeric digit(s)
CMS_PASSWORD_MISSING_UPPER_CASE=The password requires at least {0} upper case letter(s), excluding capitals in the initial position
CMS_PASSWORD_MISSING_UPPER_CASE=The password requires at least {0} upper case letter(s)
CMS_PASSWORD_MISSING_UPPER_CASE_1=The password requires at least {0} upper case letter(s)
CMS_PASSWORD_MISSING_LOWER_CASE=The password requires at least {0} lower case letter(s)
CMS_PASSWORD_MISSING_LOWER_CASE_1=The password requires at least {0} lower case letter(s)
Expand Down
29 changes: 26 additions & 3 deletions docs/admin/ServerSideKeygen.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -84,20 +84,43 @@ output.o1.class_id=pkcs12OutputImpl

=== Policyset

Password for the generated PKCS12 can be enforced with the follwing policy:
Password for the generated PKCS12 can be enforced with the following policy:

[lietaral]
[literal]
policyset.userCertSet.11.constraint.class_id=p12ExportPasswordConstraintImpl
policyset.userCertSet.11.constraint.name=PKCS12 Password Constraint
policyset.userCertSet.11.constraint.params.password.minSize=20
policyset.userCertSet.11.constraint.params.password.minCharCategory=2,2,2,2
policyset.userCertSet.11.constraint.params.password.minUpperLetter=2
policyset.userCertSet.11.constraint.params.password.minLowerLetter=2
policyset.userCertSet.11.constraint.params.password.minNumber=2
policyset.userCertSet.11.constraint.params.password.minSpecialChar=2
policyset.userCertSet.11.constraint.params.password.seqLength=6
policyset.userCertSet.11.constraint.params.password.maxRepeatedChar=3
policyset.userCertSet.11.constraint.params.password.cracklibCheck=false
policyset.userCertSet.11.default.class_id=noDefaultImpl
policyset.userCertSet.11.default.name=No Default


This policy allows to set:

* `password.minSize` - the minimum size for the passwor`d;
* `password.minUpperLetter` - the minimum number of capital letters;
* `password.minLowerLetter` - the minimum number of lower letters;
* `password.minNumber` - the minimum number of digits;
* `password.minSpecialChar` - the minimum number of punctuation characters;
* `password.seqLength` - the size of substring sequence which cannot be repeated;
* `password.maxRepeatedChar` - maximum number of repeating for each character;
* `password.cracklibCheck` - a boolean to request an additional check with *cracklib* (it has to be installed if not present).

If the constraint does not include specific configuration it will
read the options from the `CS.cfg`. In the case the name is different,
the suffix `password.*` is replaced by `passwordChecker.*`. The
configuration in `CS.cfg` are used for all the passwords but each
profile can overwrite to allow stronger or weaker passwords.




Key type and key size parameters can be configured as exemplified below:

[literal]
Expand Down
12 changes: 8 additions & 4 deletions docs/changes/v11.6.0/Server-Changes.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,12 @@ A new policy constraint is defined to enforce the password quality: *p12ExportPa
* `password.maxRepeatedChar` - maximum number of repeating for each character;
* `password.cracklibCheck` - a boolean to request an additional check with *cracklib* (it has to be installed if not present).

The same options can be configured in the `CS.cfg` replacing
`password.*` with `passwordChecker.*`. The configuration in `CS.cfg`
are used for all the passwords but each profile can overwrite to allow
stronger or weaker passwords.

These parameter can be configured in each profile using the input
*serverKeygenInputImpl* and the output *pkcs12OutputImpl*. If the
constraint does not include specific configuration it will read the
options from the `CS.cfg`. In the case the name is different, the
suffix `password.*` is replaced by `passwordChecker.*`. The configuration in
`CS.cfg` are used for all the passwords but each profile can overwrite
to allow stronger or weaker passwords.

0 comments on commit eddc530

Please sign in to comment.