2018-03-17 // Experiences with Java and X.509 Certificates - Certificate Revokation Lists
As already mentioned in the article Experiences with Java and X.509 Certificates - Code Signing i recently had the task of researching two issues involving Java and X.509 certificates. While i'm familiar with X.509 certificates, i'm not too familiar with the inner workings of Java, the Java run-time environment or let alone programming in Java. So this was a good opportunity to familiarize myself with the inner workings of Java and also a great learning experience.
The second issue, which this blog post will be about, was in the area of TLS-secured HTTPS network connections, naturally involving a X.509 certificate on the server side. In particular the server processes of two Java application servers were connecting the application logic of two different systems via an API over a HTTPS based network connection. The source system would make RPC calls to an API on the target system in order to store data in and retrieve data from this system.
The communication between the two systems would work fine while using an unencrypted HTTP based network connection, but would fail while using a secured HTTPS network connections. The errors reported back to the server process on the source system which was initiating the communication, would point in the direction of an issue with the X.509 certificate that was being used on the target server. The error message would look something like this:
%% Invalidated: [Session-1, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256] main, SEND TLSv1.2 ALERT: fatal, description = certificate_unknown main, WRITE: TLSv1.2 Alert, length = 2 [Raw write]: length = 7 0000: 15 03 03 00 02 02 2E ....... main, called closeSocket() main, handling exception: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target Exception Failed to access the WSDL at: https://hostname:port/url/rpc-call. It failed with: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target. x.y.z.ExceptionHandler at x.y.z.method1(source1.java:line-number) at x.y.z.method2(source2.java:line-number) at x.y.z.method3(source3.java:line-number)
Checking the certificate used on the side of the target server would turn up nothing unusual. The certificate was issued by the internal CA of our infrastructure and like many other certificates looked valid. Verifiying this, by initiating a non-Java based HTTPS request (e.g. with a browser) to the target system worked fine. The certificate on the side of the target server was accepted and a secured HTTPS connection was successfully established. The next debugging step was to check the certstore on the side of the source server which was initiating the connection. It showed that a valid entry, containing the full chain of the root and the intermediate certificates of our internal CA, existed.
From an infrastructure point of view, everything looked reasonably good and should work just fine. Still, the connection between the two systems was failing.
Unfortunately, but inevitably the Java routines responsible for initiating the HTTPS connection on the source system were part of and thus embedded in a programming logic more complex than necessary or useful for the purpose of low-level debugging. For further debugging i wanted a Java-based test program which was stripped down to the bare minimum of initiating a HTTPS connection. Again, not being a seasoned Java programmer, i managed to cobble together the following test program from several examples on the internet:
- CertChecker.java
import java.net.*; import java.io.*; import javax.net.ssl.*; import java.security.GeneralSecurityException; import java.security.KeyStore; import java.security.SecureRandom; import java.security.cert.*; import java.util.*; public class CertChecker implements X509TrustManager { public static void main(String[] args) throws Exception { try { SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, new TrustManager[]{new CertChecker()}, new SecureRandom()); SSLSocketFactory factory = (SSLSocketFactory)SSLSocketFactory.getDefault(); SSLSocket socket = (SSLSocket)factory.createSocket("hostname", port); socket.startHandshake(); PrintWriter out = new PrintWriter( new BufferedWriter( new OutputStreamWriter( socket.getOutputStream()))); out.println("GET / HTTP/1.0"); out.println(); out.flush(); if (out.checkError()) System.out.println("SSLSocketClient: java.io.PrintWriter error"); BufferedReader in = new BufferedReader( new InputStreamReader( socket.getInputStream())); String inputLine; while ((inputLine = in.readLine()) != null) System.out.println(inputLine); in.close(); out.close(); socket.close(); } catch (Exception e) { e.printStackTrace(); } } private final X509TrustManager defaultTM; public CertChecker() throws GeneralSecurityException { TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init((KeyStore) null); defaultTM = (X509TrustManager) tmf.getTrustManagers()[0]; } public void checkServerTrusted(X509Certificate[] certs, String authType) { if (defaultTM != null) { try { defaultTM.checkServerTrusted(certs, authType); Set<TrustAnchor> trustAnchors = getTrustAnchors(); System.out.println("Certificate valid"); } catch (CertificateException ex) { System.out.println("Certificate invalid: " + ex.getMessage()); } } } private Set<TrustAnchor> getTrustAnchors() { X509Certificate[] acceptedIssuers = defaultTM.getAcceptedIssuers(); Set<TrustAnchor> trustAnchors = new HashSet<TrustAnchor>(); for (X509Certificate acceptedIssuer : acceptedIssuers) { TrustAnchor trustAnchor = new TrustAnchor(acceptedIssuer, null); trustAnchors.add(trustAnchor); } return trustAnchors; } public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } public X509Certificate[] getAcceptedIssuers() { return null; } }
In line 16 of the above Java program, the placeholders hostname
and port
were replaced by the appropriate values for the target server system. The code was then compiled and run against the target server system, with the following Java command line call:
user@host:$ java -Djava.security.debug=all -Djavax.net.debug=all CertChecker
The result from this was the following error message output:
[...] certpath: BasicChecker.updateState issuer: CN=root-ca, DC=domain, DC=tld; subject: CN=intermediate-ca, DC=domain, DC=tld; serial#: ... certpath: -checker6 validation succeeded certpath: -Using checker7 ... [sun.security.provider.certpath.RevocationChecker] certpath: RevocationChecker.check: checking cert SN: 26000000 0cff68dd 06c50fb0 4a000100 00000c Subject: CN=intermediate-ca, DC=domain, DC=tld Issuer: CN=root-ca, DC=domain, DC=tld certpath: RevocationChecker.checkCRLs() ---checking revocation status ... certpath: RevocationChecker.checkCRLs() possible crls.size() = 0 certpath: RevocationChecker.checkCRLs() approved crls.size() = 0 certpath: DistributionPointFetcher.getCRLs: Checking CRLDPs for CN=intermediate-ca, DC=domain, DC=tld certpath: Trying to fetch CRL from DP http://crl-fqdn/filename.crl certpath: CertStore URI:http://crl-fqdn/filename.crl certpath: Downloading new CRL... certpath: Exception fetching CRL: java.security.cert.CRLException: Empty input java.security.cert.CRLException: Empty input at sun.security.provider.X509Factory.engineGenerateCRL(X509Factory.java:397) at java.security.cert.CertificateFactory.generateCRL(CertificateFactory.java:497) at sun.security.provider.certpath.URICertStore.engineGetCRLs(URICertStore.java:419) at java.security.cert.CertStore.getCRLs(CertStore.java:181) at sun.security.provider.certpath.DistributionPointFetcher.getCRL(DistributionPointFetcher.java:245) at sun.security.provider.certpath.DistributionPointFetcher.getCRLs(DistributionPointFetcher.java:189) at sun.security.provider.certpath.DistributionPointFetcher.getCRLs(DistributionPointFetcher.java:121) at sun.security.provider.certpath.RevocationChecker.checkCRLs(RevocationChecker.java:552) at sun.security.provider.certpath.RevocationChecker.checkCRLs(RevocationChecker.java:465) at sun.security.provider.certpath.RevocationChecker.check(RevocationChecker.java:367) at sun.security.provider.certpath.RevocationChecker.check(RevocationChecker.java:337) at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:125) at sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:219) at sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:140) at sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:79) at java.security.cert.CertPathValidator.validate(CertPathValidator.java:292) at sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:347) at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:249) at sun.security.validator.Validator.validate(Validator.java:260) at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324) at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229) at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124) at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1496) at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216) at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1026) at sun.security.ssl.Handshaker.process_record(Handshaker.java:961) at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062) at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387) at CertChecker.main(CertChecker.java:31) [...] %% Invalidated: [Session-1, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256] main, SEND TLSv1.2 ALERT: fatal, description = certificate_unknown main, WRITE: TLSv1.2 Alert, length = 2 [Raw write]: length = 7 0000: 15 03 03 00 02 02 2E ....... main, called closeSocket() main, handling exception: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: \ PKIX path validation failed: java.security.cert.CertPathValidatorException: Could not determine revocation status javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: \ java.security.cert.CertPathValidatorException: Could not determine revocation status at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296) at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1514) at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216) at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1026) at sun.security.ssl.Handshaker.process_record(Handshaker.java:961) at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062) at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387) at CertChecker.main(CertChecker.java:31) Caused by: sun.security.validator.ValidatorException: PKIX path validation failed: \ java.security.cert.CertPathValidatorException: Could not determine revocation status at sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:352) at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:249) at sun.security.validator.Validator.validate(Validator.java:260) at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324) at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229) at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124) at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1496) ... 8 more Caused by: java.security.cert.CertPathValidatorException: Could not determine revocation status at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:135) at sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:219) at sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:140) at sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:79) at java.security.cert.CertPathValidator.validate(CertPathValidator.java:292) at sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:347) ... 14 more Caused by: java.security.cert.CertPathValidatorException: Could not determine revocation status at sun.security.provider.certpath.RevocationChecker.buildToNewKey(RevocationChecker.java:1092) at sun.security.provider.certpath.RevocationChecker.verifyWithSeparateSigningKey(RevocationChecker.java:910) at sun.security.provider.certpath.RevocationChecker.checkCRLs(RevocationChecker.java:577) at sun.security.provider.certpath.RevocationChecker.checkCRLs(RevocationChecker.java:465) at sun.security.provider.certpath.RevocationChecker.check(RevocationChecker.java:367) at sun.security.provider.certpath.RevocationChecker.check(RevocationChecker.java:337) at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:125) ... 19 more
The Java exceptions shown above suggested an issue with the Certificate Revokation List (CRL) of the root CA. This was confusing, since the certificate worked when the target server was accessed with a browser. Manually downloading the CRL was also possibly. Verifying the downloaded CRL with the help of OpenSSL showed no anomalies to which this issue could be attributed.
The line:
java.security.cert.CRLException: Empty input
from the above error messages, lead the way to solve this issue. This line could be interpreted in two ways:
- either there was a field in the CRL currently being parsed that had an empty or an unexpected value leading to a parse error
- or the downloaded CRL data which was handed over to the CRL parsing code was an empty set.
I decided to first check option number 2 and – if this turned out to be not the case – move on from there to check option number 1. Since a manual download of the CRL worked per se, i decided to take a closer look at the download process with the curl
command line utility:
user@host:$ curl -v http://crl-fqdn/filename.crl * Hostname was NOT found in DNS cache % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Trying 10.0.0.15... * Connected to crl-fqdn (10.0.0.15) port 80 (#0) > GET /filename.crl HTTP/1.1 > User-Agent: curl/7.38.0 > Host: crl-fqdn > Accept: */* > * HTTP 1.0, assume close after body < HTTP/1.0 302 Found < Location: https://crl-fqdn/filename.crl < Server: loadbalancer-vendor * HTTP/1.0 connection set to keep alive! < Connection: Keep-Alive < Content-Length: 0 < 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 * Connection #0 to host crl-fqdn left intact
The HTTP request for the CRL file was in fact answered with a HTTP status code 302 and a new location for the CRL file, redirecting any client to a HTTPS secured location. What is apparently working for any regular browser or – with the “-L
” command line option – even for the curl
command line utility, seemed to be an issue for the part of the JRE that is handling the download of the CRL. Instead of following the HTTP redirect and requesting the CRL from the alternate location, the CRL-handling code within the JRE is given the content data that is returned from the initial HTTP request which is an empty set (see the Content-Length: 0
in the above curl
output). This in turn leads to the failure of parsing the CRL, which leads to the failure verifying the certificate against the CRL, which leads to the failure of not establishing a TLS-secured HTTPS network connection between the source and the target server system.
The immediate and simple solution to this issue was to add an exception to the HTTP-to-HTTPS redirect for the URL of the CRL. This global HTTP-to-HTTPS redirect was implemented a while ago upon request by the information security department as an attempt make the site serving the CRL and other content more secure. Arguably serving CRLs with HTTPS is generally a bad idea, since it can cause a chicken-and-egg type of problem. In this case though it would have worked, since the host serving the CRL was protected by a certificate from a different CA than the one for which the CRL was being provided.
2018-02-08 // Experiences with Java and X.509 Certificates - Code Signing
Recently i had the task of researching two issues involving Java and X.509 certificates. While i'm familiar with X.509 certificates, i'm not too familiar with the inner workings of Java, the Java run-time environment or let alone programming in Java. So this was a good opportunity to familiarize myself with the inner workings of Java and also a great learning experience.
The first issue, which this blog post will be about, was in the area of code signing of an additional third party component to Java. The second issue was in the area of HTTPS network connections and will be the subject of another blog post.
In our Windows client environment, we use the smartcard system ActivIdentity from HID in conjunction with the single sign-on software SecureLogin from NetIQ, now a part of Micro Focus. In our case primarily used for an inhouse Java based application, there is a Java extension which integrates an interface to the ActivIdentity software in the clients JRE. This aims to make the ActivIdentity smartcard system available for all Java based applications in order to provide a single sign-on feature for the users.
The Java extension consists of the files:
$JAVA_HOME/lib/ext/javasso.jar $JAVA_HOME/lib/ext/xbean.jar
During the preliminary tests for a rollout of a current release of the JRE version v1.8.0 on the Windows clients, the following issue surfaced. Probably due to the more strict enforcement of security measures in the current JRE version, the single sign-on integration would not work reliably any more, sometimes even not at all. There have previously been issues with this and a – albeit ugly – workaround implemented by our Windows client team was to disable the certificate revokation checks for the entire JRE on the Windows clients. Now, with the new JRE to be rolled out, even this workaround wouldn't get the single sign-on to work any more.
From the console of the JRE the only clue was the following, but probably unrelated, Java exception:
java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at com.actividentity.sso.javasso.awt_swing.JavaSSOHook.addListenersRecursively(JavaSSOHook.java:356) at com.actividentity.sso.javasso.awt_swing.JavaSSOHook.addListenersRecursively(JavaSSOHook.java:455) at com.actividentity.sso.javasso.awt_swing.JavaSSOHook.addListenersRecursively(JavaSSOHook.java:455) at com.actividentity.sso.javasso.awt_swing.JavaSSOHook.addListenersRecursively(JavaSSOHook.java:455) at com.actividentity.sso.javasso.awt_swing.JavaSSOHook.addListenersRecursively(JavaSSOHook.java:455) at com.actividentity.sso.javasso.awt_swing.JavaSSOHook.addListenersRecursively(JavaSSOHook.java:455) at com.actividentity.sso.javasso.awt_swing.JavaSSOJob.refreshComponentTree(JavaSSOJob.java:168) at com.actividentity.sso.javasso.JavaSSOJobMgr.refreshComponentTrees(JavaSSOJobMgr.java:93) at com.actividentity.sso.javasso.JavaSSOJobMgr.run(JavaSSOJobMgr.java:190) at java.lang.Thread.run(Unknown Source) Caused by: java.lang.NullPointerException at com.sun.proxy.$Proxy0.equals(Unknown Source) at java.util.Vector.indexOf(Unknown Source) at java.util.Vector.indexOf(Unknown Source) at java.util.Vector.removeElement(Unknown Source) at oracle.ewt.event.ListenerManager.removeListener(Unknown Source) at oracle.ewt.lwAWT.lwWindow.DesktopContainer.removeDesktopListener(Unknown Source) ... 14 more
After some searching it turned out that the file $JAVA_HOME/lib/ext/javasso.jar
, which is part of the Java extension provided by ActivIdentity, was signed with a X.509 certificate which expired in 2016:
user@host:$ openssl pkcs7 -inform DER -print_certs -in SUNCODES.RSA -noout -text Certificate: Data: Version: 3 (0x2) Serial Number: 0a:77:eb:6f:b1:d6:74:7c:f2:7d:4e:3d:43:fa:72:1c Signature Algorithm: sha1WithRSAEncryption Issuer: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=Terms of use at https://www.verisign.com/rpa (c)10, CN=VeriSign Class 3 Code Signing 2010 CA Validity Not Before: Mar 6 00:00:00 2013 GMT Not After : Jun 4 23:59:59 2016 GMT Subject: C=US, ST=Utah, L=Provo, O=Novell, Inc., OU=Digital ID Class 3 - Java Object Signing, CN=Novell, Inc. Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: 00:eb:e8:89:56:52:0f:be:7d:7a:90:8c:f6:a6:46: c2:c5:d7:8d:de:ab:9d:44:79:b9:ca:be:d3:22:94: 58:a3:b9:49:b3:59:71:52:98:ec:30:48:c3:60:32: 13:19:ec:b0:19:f6:9c:4a:4b:89:6f:fd:cc:67:f1: a4:c0:b6:37:b9:c7:3c:58:aa:0d:0e:cd:dc:06:ff: 17:64:ec:a9:9d:29:ef:ae:5b:49:ef:8c:ef:8c:38: a4:1b:ec:b5:26:c2:65:80:c3:cf:b8:73:d5:e7:dc: e2:54:3f:63:c8:c4:12:40:57:dd:9a:bc:56:ad:6a: bc:65:a8:34:a0:df:d1:87:58:2c:06:65:74:a0:48: 0f:df:41:e4:6b:9b:d5:45:f2:3f:3a:c3:a9:c1:84: bf:a0:d4:fa:ee:53:a3:09:51:b5:18:bf:98:aa:f0: 6e:77:8a:c1:fd:1c:4d:62:47:ca:2d:ae:93:4c:5a: ae:32:39:eb:cc:4b:da:fe:cb:e7:5f:02:af:d1:c4: 5f:6b:d5:e0:3c:06:3c:3a:29:83:bc:c7:10:7a:4c: 9a:ff:ff:bd:84:62:a8:4c:bf:76:20:b8:d8:20:9c: f7:86:3b:96:d4:30:52:30:66:f5:9f:48:59:e1:1c: 2d:10:e8:6b:67:be:8f:21:41:be:83:af:9f:e7:41: 10:73 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: CA:FALSE X509v3 Key Usage: critical Digital Signature X509v3 CRL Distribution Points: Full Name: URI:http://csc3-2010-crl.verisign.com/CSC3-2010.crl X509v3 Certificate Policies: Policy: 2.16.840.1.113733.1.7.23.3 CPS: https://www.verisign.com/rpa X509v3 Extended Key Usage: Code Signing Authority Information Access: OCSP - URI:http://ocsp.verisign.com CA Issuers - URI:http://csc3-2010-aia.verisign.com/CSC3-2010.cer X509v3 Authority Key Identifier: keyid:CF:99:A9:EA:7B:26:F4:4B:C9:8E:8F:D7:F0:05:26:EF:E3:D2:A7:9D Netscape Cert Type: Object Signing 1.3.6.1.4.1.311.2.1.27: 0....... Signature Algorithm: sha1WithRSAEncryption 40:18:43:e9:58:06:c5:3e:82:de:ec:8e:69:20:26:43:3f:0b: 41:0f:1b:cf:ca:5d:f6:e2:f2:c3:31:e7:c3:d0:07:f4:ea:8e: d5:1f:72:de:1e:4c:d6:8a:d6:c5:87:5a:7b:d5:46:d1:18:1b: 85:5c:d2:fe:62:76:ff:94:e9:7a:db:32:99:51:9a:36:55:c4: b1:5e:f0:9a:0b:42:07:2e:ce:b6:84:d7:20:b6:51:ef:f6:c7: 20:fd:7d:95:68:52:f3:91:6f:5e:5f:25:3f:13:ee:f2:8d:75: 2c:ef:b4:26:43:c5:dc:af:78:9c:45:b7:04:87:b8:a1:fd:c3: f4:84:7e:91:97:12:02:ad:d9:16:5a:45:62:56:85:03:71:90: a9:cf:61:01:9b:6d:8d:9e:59:bc:fc:8f:46:de:27:db:71:e2: 58:13:d2:fb:1b:e0:58:f0:9f:2d:3a:bc:ca:12:78:33:d3:7a: 76:95:7e:53:c2:2b:4d:fb:6d:bb:92:8f:c6:28:0f:15:1d:af: 7d:60:b5:a3:21:b3:66:e1:44:ab:91:10:85:d2:20:44:45:96: 2c:14:3e:c1:87:92:ae:a9:d6:a9:84:2a:5e:15:6c:d8:bf:37: f2:33:2e:cc:64:49:ce:2c:e8:30:84:22:2c:b6:a9:c1:fc:30: 97:48:d1:fa Certificate: Data: Version: 3 (0x2) Serial Number: 52:00:e5:aa:25:56:fc:1a:86:ed:96:c9:d4:4b:33:c7 Signature Algorithm: sha1WithRSAEncryption Issuer: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5 Validity Not Before: Feb 8 00:00:00 2010 GMT Not After : Feb 7 23:59:59 2020 GMT Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=Terms of use at https://www.verisign.com/rpa (c)10, CN=VeriSign Class 3 Code Signing 2010 CA Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: 00:f5:23:4b:5e:a5:d7:8a:bb:32:e9:d4:57:f7:ef: e4:c7:26:7e:ad:19:98:fe:a8:9d:7d:94:f6:36:6b: 10:d7:75:81:30:7f:04:68:7f:cb:2b:75:1e:cd:1d: 08:8c:df:69:94:a7:37:a3:9c:7b:80:e0:99:e1:ee: 37:4d:5f:ce:3b:14:ee:86:d4:d0:f5:27:35:bc:25: 0b:38:a7:8c:63:9d:17:a3:08:a5:ab:b0:fb:cd:6a: 62:82:4c:d5:21:da:1b:d9:f1:e3:84:3b:8a:2a:4f: 85:5b:90:01:4f:c9:a7:76:10:7f:27:03:7c:be:ae: 7e:7d:c1:dd:f9:05:bc:1b:48:9c:69:e7:c0:a4:3c: 3c:41:00:3e:df:96:e5:c5:e4:94:71:d6:55:01:c7: 00:26:4a:40:3c:b5:a1:26:a9:0c:a7:6d:80:8e:90: 25:7b:cf:bf:3f:1c:eb:2f:96:fa:e5:87:77:c6:b5: 56:b2:7a:3b:54:30:53:1b:df:62:34:ff:1e:d1:f4: 5a:93:28:85:e5:4c:17:4e:7e:5b:fd:a4:93:99:7f: df:cd:ef:a4:75:ef:ef:15:f6:47:e7:f8:19:72:d8: 2e:34:1a:a6:b4:a7:4c:7e:bd:bb:4f:0c:3d:57:f1: 30:d6:a6:36:8e:d6:80:76:d7:19:2e:a5:cd:7e:34: 2d:89 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: critical CA:TRUE, pathlen:0 X509v3 Certificate Policies: Policy: 2.16.840.1.113733.1.7.23.3 CPS: https://www.verisign.com/cps User Notice: Explicit Text: https://www.verisign.com/rpa X509v3 Key Usage: critical Certificate Sign, CRL Sign 1.3.6.1.5.5.7.1.12: 0_.].[0Y0W0U..image/gif0!0.0...+..............k...j.H.,{..0%.#http://logo.verisign.com/vslogo.gif X509v3 CRL Distribution Points: Full Name: URI:http://crl.verisign.com/pca3-g5.crl Authority Information Access: OCSP - URI:http://ocsp.verisign.com X509v3 Extended Key Usage: TLS Web Client Authentication, Code Signing X509v3 Subject Alternative Name: DirName:/CN=VeriSignMPKI-2-8 X509v3 Subject Key Identifier: CF:99:A9:EA:7B:26:F4:4B:C9:8E:8F:D7:F0:05:26:EF:E3:D2:A7:9D X509v3 Authority Key Identifier: keyid:7F:D3:65:A7:C2:DD:EC:BB:F0:30:09:F3:43:39:FA:02:AF:33:31:33 Signature Algorithm: sha1WithRSAEncryption 56:22:e6:34:a4:c4:61:cb:48:b9:01:ad:56:a8:64:0f:d9:8c: 91:c4:bb:cc:0c:e5:ad:7a:a0:22:7f:df:47:38:4a:2d:6c:d1: 7f:71:1a:7c:ec:70:a9:b1:f0:4f:e4:0f:0c:53:fa:15:5e:fe: 74:98:49:24:85:81:26:1c:91:14:47:b0:4c:63:8c:bb:a1:34: d4:c6:45:e8:0d:85:26:73:03:d0:a9:8c:64:6d:dc:71:92:e6: 45:05:60:15:59:51:39:fc:58:14:6b:fe:d4:a4:ed:79:6b:08: 0c:41:72:e7:37:22:06:09:be:23:e9:3f:44:9a:1e:e9:61:9d: cc:b1:90:5c:fc:3d:d2:8d:ac:42:3d:65:36:d4:b4:3d:40:28: 8f:9b:10:cf:23:26:cc:4b:20:cb:90:1f:5d:8c:4c:34:ca:3c: d8:e5:37:d6:6f:a5:20:bd:34:eb:26:d9:ae:0d:e7:c5:9a:f7: a1:b4:21:91:33:6f:86:e8:58:bb:25:7c:74:0e:58:fe:75:1b: 63:3f:ce:31:7c:9b:8f:1b:96:9e:c5:53:76:84:5b:9c:ad:91: fa:ac:ed:93:ba:5d:c8:21:53:c2:82:53:63:af:12:0d:50:87: 11:1b:3d:54:52:96:8a:2c:9c:3d:92:1a:08:9a:05:2e:c7:93: a5:48:91:d3
Due to a dependency between the smartcard readers installed at our Windows clients, farious driver and software versions, an update to the current and properly signed Java extension provided by ActivIdentity was not possible. The most immediate solution to this issue was to remove the original code signing information from the file $JAVA_HOME/lib/ext/javasso.jar
and – for security purposes – to re-sign it with a still valid code signing certificate from our internal CA which is trusted by our Windows clients.