Skip to content

Commit

Permalink
Update cert approval callback
Browse files Browse the repository at this point in the history
Previously if a client tries to connect to a server but it does
not have the CA signing cert installed and trusted it will get an
UNTRUSTED_ISSUER error from NSS and the cert approval callback
will ask the user whether to trust the cert. In the latest NSS
the error has changed to UNKNOWN_ISSUER, so the callback has been
updated to handle the error in the same way. The tests have also
been updated accordingly.
  • Loading branch information
edewata committed Aug 21, 2024
1 parent 9615892 commit 64f3239
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 16 deletions.
10 changes: 5 additions & 5 deletions .github/workflows/server-https-nss-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ jobs:
-o /dev/null \
https://pki.example.com:8443
- name: Check PKI CLI with untrusted server cert
- name: Check PKI CLI with unknown issuer
run: |
# run PKI CLI but don't trust the cert
echo n | docker exec -i client pki -U https://pki.example.com:8443 info \
Expand All @@ -178,7 +178,7 @@ jobs:
# check stderr
cat > expected << EOF
WARNING: UNTRUSTED ISSUER encountered on 'CN=pki.example.com' indicates a non-trusted CA cert 'CN=CA Signing Certificate'
WARNING: UNKNOWN_ISSUER encountered on 'CN=pki.example.com' indicates an unknown CA cert 'CN=CA Signing Certificate'
Trust this certificate (y/N)? SEVERE: FATAL: SSL alert sent: BAD_CERTIFICATE
IOException: Unable to write to socket: Failed to write to socket: (-5987) Invalid function argument.
EOF
Expand All @@ -190,7 +190,7 @@ jobs:
diff /dev/null output
- name: Check PKI CLI with untrusted server cert with wrong hostname
- name: Check PKI CLI with unknown issuer with wrong hostname
run: |
# run PKI CLI with wrong hostname
echo n | docker exec -i client pki -U https://server.example.com:8443 info \
Expand All @@ -205,8 +205,8 @@ jobs:
# check stderr
cat > expected << EOF
WARNING: UNKNOWN_ISSUER encountered on 'CN=pki.example.com' indicates an unknown CA cert 'CN=CA Signing Certificate'
WARNING: BAD_CERT_DOMAIN encountered on 'CN=pki.example.com' indicates a common-name mismatch
WARNING: UNTRUSTED ISSUER encountered on 'CN=pki.example.com' indicates a non-trusted CA cert 'CN=CA Signing Certificate'
Trust this certificate (y/N)? SEVERE: FATAL: SSL alert sent: BAD_CERTIFICATE
IOException: Unable to write to socket: Failed to write to socket: (-12276) Unable to communicate securely with peer: requested domain name does not match the server's certificate.
EOF
Expand All @@ -229,7 +229,7 @@ jobs:
# check stderr
cat > expected << EOF
WARNING: UNTRUSTED ISSUER encountered on 'CN=pki.example.com' indicates a non-trusted CA cert 'CN=CA Signing Certificate'
WARNING: UNKNOWN_ISSUER encountered on 'CN=pki.example.com' indicates an unknown CA cert 'CN=CA Signing Certificate'
Trust this certificate (y/N)?
EOF
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/server-https-pkcs12-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ jobs:
-o /dev/null \
https://pki.example.com:8443
- name: Check PKI CLI with untrusted server cert
- name: Check PKI CLI with unknown issuer
run: |
# run PKI CLI but don't trust the cert
echo n | docker exec -i client pki \
Expand All @@ -214,7 +214,7 @@ jobs:
# check stderr
cat > expected << EOF
WARNING: UNTRUSTED ISSUER encountered on 'CN=pki.example.com' indicates a non-trusted CA cert 'CN=CA Signing Certificate'
WARNING: UNKNOWN_ISSUER encountered on 'CN=pki.example.com' indicates an unknown CA cert 'CN=CA Signing Certificate'
Trust this certificate (y/N)? SEVERE: FATAL: SSL alert sent: BAD_CERTIFICATE
IOException: Unable to write to socket: Failed to write to socket: (-5987) Invalid function argument.
EOF
Expand All @@ -226,7 +226,7 @@ jobs:
diff /dev/null output
- name: Check PKI CLI with untrusted server cert and wrong hostname
- name: Check PKI CLI with unknown issuer and wrong hostname
run: |
# run PKI CLI with wrong hostname
echo n | docker exec -i client pki \
Expand All @@ -243,8 +243,8 @@ jobs:
# check stderr
cat > expected << EOF
WARNING: UNKNOWN_ISSUER encountered on 'CN=pki.example.com' indicates an unknown CA cert 'CN=CA Signing Certificate'
WARNING: BAD_CERT_DOMAIN encountered on 'CN=pki.example.com' indicates a common-name mismatch
WARNING: UNTRUSTED ISSUER encountered on 'CN=pki.example.com' indicates a non-trusted CA cert 'CN=CA Signing Certificate'
Trust this certificate (y/N)? SEVERE: FATAL: SSL alert sent: BAD_CERTIFICATE
IOException: Unable to write to socket: Failed to write to socket: (-12276) Unable to communicate securely with peer: requested domain name does not match the server's certificate.
EOF
Expand All @@ -269,7 +269,7 @@ jobs:
# check stderr
cat > expected << EOF
WARNING: UNTRUSTED ISSUER encountered on 'CN=pki.example.com' indicates a non-trusted CA cert 'CN=CA Signing Certificate'
WARNING: UNKNOWN_ISSUER encountered on 'CN=pki.example.com' indicates an unknown CA cert 'CN=CA Signing Certificate'
Trust this certificate (y/N)?
EOF
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,17 @@ public String getMessage(org.mozilla.jss.crypto.X509Certificate serverCert, int
}

if (reason == SSLCertificateApprovalCallback.ValidityStatus.UNTRUSTED_ISSUER) {
return "UNTRUSTED ISSUER encountered on '" +
return "UNTRUSTED_ISSUER encountered on '" +
serverCert.getSubjectDN() + "' indicates a non-trusted CA cert '" +
serverCert.getIssuerDN() + "'";
}

if (reason == SSLCertificateApprovalCallback.ValidityStatus.UNKNOWN_ISSUER) {
return "UNKNOWN_ISSUER encountered on '" +
serverCert.getSubjectDN() + "' indicates an unknown CA cert '" +
serverCert.getIssuerDN() + "'";
}

if (reason == SSLCertificateApprovalCallback.ValidityStatus.CA_CERT_INVALID) {
return "CA_CERT_INVALID encountered on '"+serverCert.getSubjectDN()+"' results in a denied SSL server cert!";
}
Expand All @@ -126,7 +132,7 @@ public String getMessage(org.mozilla.jss.crypto.X509Certificate serverCert, int
return "Unknown/undefined reason "+reason+" encountered on '"+serverCert.getSubjectDN()+"' results in a denied SSL server cert!";
}

public boolean handleUntrustedIssuer(org.mozilla.jss.crypto.X509Certificate serverCert) {
public boolean trustCert(org.mozilla.jss.crypto.X509Certificate serverCert) {
try {
System.err.print("Trust this certificate (y/N)? ");

Expand Down Expand Up @@ -172,7 +178,9 @@ public boolean approve(X509Certificate cert, ValidityStatus status) {
// continue, or you can continue to make further tests of
// your own to determine trustworthiness.
Enumeration<?> errors = status.getReasons();

boolean approval = true;
boolean prompt = false;

while (errors.hasMoreElements()) {
SSLCertificateApprovalCallback.ValidityItem item =
Expand All @@ -193,14 +201,13 @@ public boolean approve(X509Certificate cert, ValidityStatus status) {
} else if (isIgnored(reason)) {
// Ignore validity status

} else if (reason == SSLCertificateApprovalCallback.ValidityStatus.UNTRUSTED_ISSUER) {
} else if (reason == SSLCertificateApprovalCallback.ValidityStatus.UNTRUSTED_ISSUER
|| reason == SSLCertificateApprovalCallback.ValidityStatus.UNKNOWN_ISSUER) {
// Issue a WARNING, but allow this process
// to continue since we haven't installed a trusted CA
// cert for this operation.
System.err.println("WARNING: " + getMessage(serverCert, reason));
if (!handleUntrustedIssuer(serverCert)) {
approval = false;
}
prompt = true;

} else if (reason == SSLCertificateApprovalCallback.ValidityStatus.BAD_CERT_DOMAIN) {
// Issue a WARNING, but allow this process to continue on
Expand All @@ -224,6 +231,10 @@ public boolean approve(X509Certificate cert, ValidityStatus status) {
}
}

if (prompt && !trustCert(serverCert)) {
approval = false;
}

return approval;
}
}

0 comments on commit 64f3239

Please sign in to comment.