ADDITIONAL SYSTEM INFORMATION :
C:\work\java\jdk-11.0.2\bin>java -version
openjdk version "11.0.2" 2019-01-15
OpenJDK Runtime Environment 18.9 (build 11.0.2+9)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.2+9, mixed mode)
Windows 10
A DESCRIPTION OF THE PROBLEM :
Verification of OCSP Response signed with RSASSA-PSS fails even it works with openssl library.
Java runtime throws an exception with message "Parameters required for RSASSA-PSS signatures" during trying to verify the signature of an OCSP Response.
Certificate under test has an intermediate and root certificate in chain but OCSP Response is signed by another certificate, which is signed by the same root.
OCSP Response contains the signer certificate. Java can verify the OCSP signer certificate but verification of the Response message fails. Same certificate chain can be verified by the openssl command line tool.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Use Java CertPathValidator.validate method to validate the revocation status of a certificate and see that it is not working due to an internal error.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Results returned by Java about the revocation status should be consistent with the openssl library since certificate is not revoked.
Response from openssl:
edi_vertrieb_strom_abita@datenaustausch-service.de.cer: good
This Update: Sep 21 15:31:32 2021 GMT
Next Update: Sep 21 16:31:32 2021 GMT
Response verify OK
ACTUAL -
Example program is started with -Djava.security.auth.debug=certpath,ocsp
start program
...
certpath: KeySizeConstraints.permits(): RSA
certpath: Responder's certificate includes the extension id-pkix-ocsp-nocheck.
certpath: OCSP response is signed by an Authorized Responder
...
certpath: RevocationChecker.check() java.security.SignatureException: Parameters required for RSASSA-PSS signatures
certpath: RevocationChecker.check() preparing to failover
.....
Parameters required for RSASSA-PSS signatures
end program
---------- BEGIN SOURCE ----------
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.Security;
import java.security.cert.CertPath;
import java.security.cert.CertPathValidator;
import java.security.cert.CertPathValidatorException;
import java.security.cert.CertPathValidatorResult;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.PKIXParameters;
import java.util.Arrays;
import java.util.Date;
public class Main {
private static final String APPLICATION = "-----BEGIN CERTIFICATE-----\n" +
"MIIHATCCBLWgAwIBAgIIBzJDL6Dfy7swQQYJKoZIhvcNAQEKMDSgDzANBglghkgB\n" +
"ZQMEAgEFAKEcMBoGCSqGSIb3DQEBCDANBglghkgBZQMEAgEFAKIDAgEgMGQxMDAu\n" +
"BgNVBAMMJ3Byb2NpbG9uIEdST1VQIEN1c3RvbWVyIENBIC0gRURJRkFDVCAwMjEP\n" +
"MA0GA1UECwwGU3ViIENBMRIwEAYDVQQKDAlTUEktQ0xPVUQxCzAJBgNVBAYTAkRF\n" +
"MB4XDTIwMDQxNDEzNDA0MVoXDTIzMDQxNDEzNDA0MVowgcoxQTA/BgkqhkiG9w0B\n" +
"CQEWMmVkaV92ZXJ0cmllYl9zdHJvbV9hYml0YUBkYXRlbmF1c3RhdXNjaC1zZXJ2\n" +
"aWNlLmRlMRUwEwYDVQQDDAxWZXJ0cmllYiBTV0sxETAPBgNVBAsMCFZlcnRyaWVi\n" +
"MTUwMwYDVQQKDCxTV0sgU3RhZHR3ZXJrZSBLYWlzZXJzbGF1dGVybiBWZXJzb3Jn\n" +
"dW5ncy1BRzEXMBUGA1UEBwwOS2Fpc2Vyc2xhdXRlcm4xCzAJBgNVBAYTAkRFMIIB\n" +
"IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAg7bTfGMD8uXn0zPdCjjS3XqP\n" +
"b5v7R9dJVU2tpHTImlYFRKPqrnm0tJ2y1pvbk3iq9TUuJ7aK83n16cnLsE+IwW7f\n" +
"I2QcJjF5iVB+WAtw8oRHReY+rvsdX4VtlCjDDrfOfB1XVE6FjWjwy7sS938+bDe+\n" +
"r2Y9t2dpW2mZQ7TLhJRBebhHPrQNtZD/l5cWNPDsSY2y2Ir5eI0eko9C+m3HQThD\n" +
"sNS5C9tPHDoHy+rKWGmgl5jd+DsKQCu79308vhw+e1zmq0IF1GIVXrlzY3cLcBrP\n" +
"3WY4fNWfn6b0HVrtLSPjenn7b5cKEG3qEbjfQ8IUpDny2S4fa0jgeacCMNIL5wID\n" +
"AQABo4IB5jCCAeIwawYIKwYBBQUHAQEEXzBdMCwGCCsGAQUFBzAChiBodHRwczov\n" +
"L3BraS5zcGktY2xvdWQuY29tL2lzc3VlcjAtBggrBgEFBQcwAYYhaHR0cDovL29j\n" +
"c3Auc3BpLWNsb3VkLmNvbS9zdGF0dXMvMB0GA1UdDgQWBBS5fNPRn5R3jnOUNZea\n" +
"qIBdyUkIkDAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFLRScBn+HHr8CzX4H8cM\n" +
"Rxb4nKbbMIHABgNVHR8EgbgwgbUwgbKgRqBEhkJodHRwOi8vcGtpLnNwaS1jbG91\n" +
"ZC5jb20vY3JsL3Byb2NpbG9uX0dST1VQX0N1c3RvbWVyX0NBX0VESUZBQ1RfMDKi\n" +
"aKRmMGQxMDAuBgNVBAMMJ3Byb2NpbG9uIEdST1VQIEN1c3RvbWVyIENBIC0gRURJ\n" +
"RkFDVCAwMjEPMA0GA1UECwwGU3ViIENBMRIwEAYDVQQKDAlTUEktQ0xPVUQxCzAJ\n" +
"BgNVBAYTAkRFMA4GA1UdDwEB/wQEAwIEsDATBgNVHSUEDDAKBggrBgEFBQcDBDA9\n" +
"BgNVHREENjA0gTJlZGlfdmVydHJpZWJfc3Ryb21fYWJpdGFAZGF0ZW5hdXN0YXVz\n" +
"Y2gtc2VydmljZS5kZTBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAQUAoRww\n" +
"GgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAQUAogMCASADggIBAGHartmLOBxHHS7W\n" +
"owTM0RaZ1rODYVwLiRPBUATZEbReco/wtbyPu3PhmDORutQsf3UF6dhgpw3Kgmvi\n" +
"r0FuWp76YIpJ6eEtgycOw9nO9Qxv6m6eOJVUh8IB+ri2G0mdWwI/HON7FGPgXeeU\n" +
"56zlK+REwD54uZ2pkIK/O13DmebcxzGnVj4BxfaFFdv4bwypYTvUzlAzExI/yewy\n" +
"1A0TNEopz3SHZKavKBaQ7+baYcqWpsDPL5LqU7JpmWLOjtQgY5LT1hpDxowt1IKd\n" +
"kfJQBmjeKReJVHrbdgYKuXb6OsBujoVWGHkFInCGmJuAWjVLEUSTuiMAFV6kY+u2\n" +
"3FSWMoDg3wZeQ1ToYgBWXuV4+rgoVKLIQxrZ6D8VygDFJTLg8aoeIMKOUCArdTR1\n" +
"7VUHCbnXaxDObKErSI6UWAIYcdfRAb+5yN8Jp/eRGjAZN/eHch6UakKLVypR2E+h\n" +
"Yjrw9wR4j8eKG/k7+guRst9J4Qxn71jxBha3Bjp9+20uwByz40/nT5+wB5rxxoDN\n" +
"Oz67KutDqgQPufvlQBe2/2QJs/TUWifJkQuD3+5XHlBYcyoIJYkZZiO+AVlIbeU5\n" +
"iZ6FNs5led6EN3bk+ZzJHNh+DNEpCrsZnkOsT52Npj8FRyg/84Zy/5pJUr/gCyRS\n" +
"AffV+edGqkmMRrHUxqZ4zMecnn2B\n" +
"-----END CERTIFICATE-----\n";
private static final String INTERMEDIATE = "-----BEGIN CERTIFICATE-----\n" +
"MIIHPDCCBPCgAwIBAgIITbAjxatoRTgwQQYJKoZIhvcNAQEKMDSgDzANBglghkgB\n" +
"ZQMEAgEFAKEcMBoGCSqGSIb3DQEBCDANBglghkgBZQMEAgEFAKIDAgEgMF8xKjAo\n" +
"BgNVBAMMIXByb2NpbG9uIEdST1VQIEN1c3RvbWVyIFJvb3RDQSAwMjEQMA4GA1UE\n" +
"CwwHUm9vdCBDQTESMBAGA1UECgwJU1BJLUNMT1VEMQswCQYDVQQGEwJERTAeFw0x\n" +
"OTEyMDIxMTE1MzBaFw0yNDExMzAxMTE1MzBaMGQxMDAuBgNVBAMMJ3Byb2NpbG9u\n" +
"IEdST1VQIEN1c3RvbWVyIENBIC0gRURJRkFDVCAwMjEPMA0GA1UECwwGU3ViIENB\n" +
"MRIwEAYDVQQKDAlTUEktQ0xPVUQxCzAJBgNVBAYTAkRFMIICIjANBgkqhkiG9w0B\n" +
"AQEFAAOCAg8AMIICCgKCAgEAg4m1dq9k2xFYoRigYgHkiSBnuI3nDtIgD9ISWuMB\n" +
"AqYffalpceOT/kK3qmhW4h/bease6GdnBwF5oudB+QpIkD1Bc3eB2rDHrBybYrF9\n" +
"FDT6QaWXb7IoBN1DXQsZoS5VdZMVBx+uvmq9l6XAgA9UwA67hZ3jy8mWcv7umlVU\n" +
"Ukak1682xRUt2VU2z02A2ax4PCTyHb20XMVNTlvbhmhhsphXIia7XgDQ65/a7i5d\n" +
"Hl3tHZX9V2fGRwMxWgNSN3N66xasNVahtzGXKrF8sc93RHxu67P+/JCiaUs5OBBU\n" +
"Gt60DC0FrswljKSSBvANwQgMSgDbR2uNTos1qAfbkVMNRgcotEUrnjv8n9QUCC1V\n" +
"6GyPUzAmyCeHDfubbJHY/GycqZewX2EqJJJNER69aX6/sHDsnUZ2X8AHmNYWDc1r\n" +
"5tsw8MEJLwL7mZOox185rYjOAsOvBdod+0wRHGRqL5qECmI0ntXf6cAOgNB7kzy1\n" +
"stqRJSQcCOqq91FTX0TFU0WTr3qGDfztaLDBQMw4tvpy5pLDK+aFUMWCe0cwDgne\n" +
"1D+T/F5AKQrduosmlq5FIPMyhxixFPBg4xn3dWWorCRWxvzDDkvUFK1zrQ7dZAWO\n" +
"V06dhRjrxXyCakDh3FFn/LAs24XUS8MnowpqpX/mUdsxlz1TiKkAZW5r67Lq6Z0s\n" +
"krMCAwEAAaOCAY0wggGJMGkGCCsGAQUFBwEBBF0wWzAqBggrBgEFBQcwAoYeaHR0\n" +
"cHM6Ly9wa2kucHJvdGVjdHIuZGUvaXNzdWVyMC0GCCsGAQUFBzABhiFodHRwOi8v\n" +
"b2NzcC5zcGktY2xvdWQuY29tL3N0YXR1cy8wHQYDVR0OBBYEFLRScBn+HHr8CzX4\n" +
"H8cMRxb4nKbbMBIGA1UdEwEB/wQIMAYBAf8CAQAwHwYDVR0jBBgwFoAUIUT6yHSx\n" +
"qwB8Kh41w07l/dyQR6gwgbcGA1UdHwSBrzCBrDCBqaBCoECGPmh0dHA6Ly9wa2ku\n" +
"c3BpLWNsb3VkLmNvbS9jcmwvcHJvY2lsb25fR1JPVVBfQ3VzdG9tZXJfUm9vdENB\n" +
"XzAyomOkYTBfMSowKAYDVQQDDCFwcm9jaWxvbiBHUk9VUCBDdXN0b21lciBSb290\n" +
"Q0EgMDIxEDAOBgNVBAsMB1Jvb3QgQ0ExEjAQBgNVBAoMCVNQSS1DTE9VRDELMAkG\n" +
"A1UEBhMCREUwDgYDVR0PAQH/BAQDAgEGMEEGCSqGSIb3DQEBCjA0oA8wDQYJYIZI\n" +
"AWUDBAIBBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAIBBQCiAwIBIAOCAgEA\n" +
"DDEUZGm5GF2xkOLhDFXwJwfIh5FRM1Vp3LMWhzAqIeLigKJctniQ0eJ53z9b5zmf\n" +
"deU5mVz42D6mqtybjuBwQtSCeBVYkuCFtt/tWz0yelOgmp12R/+TJamQX0MxTEXh\n" +
"hY2xXqZxNHittzVQXXERe5taMhPLem5lQxDg4msdvzkAyvNyUeWss7RGM5nA/ycX\n" +
"aQ58o5sbLmnbf+rXotlPHnhpQDOMiUaKifCx5i3Ox2yBwQWYjvy2Xwcf7ZCCmuSD\n" +
"WBFzNCF7GevEihcW47IF2EIwRzq1mKMWuxlDLjJ9VU9uQY1XcP8wQtebCzdh7nIS\n" +
"Uy63yrIngXrWOTac7481Z1lFj7CA0J3bNc42PJJQ50+rQU48fGJnUuUBPItAS3Ej\n" +
"RzRRLScJ1SzuDGDKldxy5fpB7y+doTvZB2v5/a3OjF7XinUes5adgwjWlNVDXZtZ\n" +
"hoHAjhXFnCPnsecbFdPq/EiYa/ozBL9vqoJ60EKXb7FgFVbOZEgM/3W0ginuiSy7\n" +
"b4nh8GHFu+Z8CWiDMkfVwPw6CKWAD/+7fBHxF6sNE2U+ptnx2AdIZDLw4GUtbKU9\n" +
"OlZAHrziQXUNEs07dHobPXC8cnIaEL8cCmOra7gt2G5W4WE5SA7YmH43RHIzKbmo\n" +
"PUyVS7rvDAZzdLmrlBtBf933c1g9Hc3BTG2DNJylPqo=\n" +
"-----END CERTIFICATE-----\n";
private static final String ROOT = "-----BEGIN CERTIFICATE-----\n" +
"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\n" +
"-----END CERTIFICATE-----\n";
public static void main(String[] args) {
System.out.println("start program");
// Execute with
// -Djava.security.auth.debug=certpath
// to see debug output from java
executeValidation(APPLICATION, INTERMEDIATE, ROOT);
System.out.println("end program");
}
private static void executeValidation(String application, String intermediate, String root) {
try {
KeyStore keyStore = KeyStore.getInstance("JCEKS");
keyStore.load(null, "".toCharArray());
CertificateFactory cf = CertificateFactory.getInstance("X509");
Certificate applicationCertificate = cf
.generateCertificate(new ByteArrayInputStream(application.getBytes()));
Certificate intermediateCertificate = cf
.generateCertificate(new ByteArrayInputStream(intermediate.getBytes()));
Certificate rootCertificate = cf.generateCertificate(new ByteArrayInputStream(root.getBytes()));
keyStore.setCertificateEntry("application", applicationCertificate);
keyStore.setCertificateEntry("intermediate", intermediateCertificate);
keyStore.setCertificateEntry("root", rootCertificate);
String result = processValidationInternal(keyStore, applicationCertificate, true, false, true);
System.out.println(result);
} catch (IOException | GeneralSecurityException e) {
e.printStackTrace();
}
}
private static String processValidationInternal(KeyStore keyStore, Certificate certificate,
boolean revocationCheckEnabled,
boolean ignoreRevocationCheckFailures,
boolean oscpCheckEnabled) {
if (revocationCheckEnabled) {
System.setProperty("com.sun.security.enableCRLDP", "true");
if (oscpCheckEnabled) {
Security.setProperty("ocsp.enable", "true");
}
} else {
System.setProperty("com.sun.security.enableCRLDP", "false");
Security.setProperty("ocsp.enable", "false");
}
String warning = null;
try {
CertificateFactory cf = CertificateFactory.getInstance(certificate.getType());
CertPath certificatePath = cf.generateCertPath(Arrays.asList(certificate));
CertPathValidator cpv = CertPathValidator.getInstance(CertPathValidator.getDefaultType());
PKIXParameters defaultStoreParams = new PKIXParameters(keyStore);
defaultStoreParams.setRevocationEnabled(revocationCheckEnabled);
defaultStoreParams.setDate(new Date(System.currentTimeMillis()));
CertPathValidatorResult defaultStoreResult = cpv.validate(certificatePath, defaultStoreParams);
if (defaultStoreResult != null) {
// Default key store validates the certificate chain.
warning = "success";
}
} catch (CertPathValidatorException e) {
warning = e.getCause().getMessage();
} catch (RuntimeException | GeneralSecurityException e) {
System.out.println("Key store can not validate certificate:" + e.getMessage());
warning = e.getCause().getMessage();
}
return warning;
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Use openssl ocsp verification tool instead of java:
openssl ocsp -CAfile ROOT.cer -issuer INTERMEDIATE.cer -cert APPLICATION.cer -text -url http://ocsp.spi-cloud.com/status/
FREQUENCY : always