Applet Certificate CRL Distribution Point LDAP URL with no host - java

I'm developing a web application that uses applets signed with a certificate issued by the customer CA. That certificate contains an URL to a CRL Distribution Point that does not define the host and port. The certificate attributes "CRL Distribution Points" and "Authority Information Access" contain an URL similar to "ldap:///CN=my-cn...".
The log files generated by the Certificate Revocation-Checking API (C:\Users[my_user]\AppData\LocalLow\Sun\Java\Deployment\log) indicate that the values "localhost" and "389" are being used for host and port. This is a snippet of the log file:
...
certpath: DistributionPointFetcher.getCRLs: Checking CRLDPs for CN=xxx, O=yyy, L=zzz, C=PT
certpath: Trying to fetch CRL from DP ldap:///CN=_my-cn_?certificateRevocationList?base?objectClass=cRLDistributionPoint
certpath: CertStore URI:ldap:///CN=_my-cn_?certificateRevocationList?base?objectClass=cRLDistributionPoint
...
network: Connecting http://localhost:389/ with proxy=DIRECT
...
certpath: LDAPCertStore.engineInit about to throw InvalidAlgorithmParameterException
javax.naming.CommunicationException: localhost:389 [Root exception is java.net.ConnectException: Connection refused: connect]
at com.sun.jndi.ldap.Connection.<init>(Unknown Source)
...
Can anyone confirm that the host is mandatory, otherwise the default value "localhost" is used?
I read in the LDAP RFC (http://www.ietf.org/rfc/rfc4516.txt) that if the "host" field is not present, the client must have some a priori knowledge of an appropriate LDAP server to contact. Is it possible to configure the "host" attribute?
I'm using the JRE version 1.7.0_45 (build 1.7.0_45-b18).
Thank you,
Telmo Simões

Yes, the host is mandatory.
It depends a bit on how (if) your code creates the LDAPCertStore object. When you call the constructor, you need to pass an LDAPCertStoreParameters object to it. That class contains a contructor which allows you to specify the host (and port).
Try creating your LDAPCertStore like this:
LDAPCertStoreParameters params = new LDAPCertStoreParameters( "hostname", 389 );
CertStore store = CertStore.getInstance("LDAP", params);
Good luck.

Related

rc=2059 amq9503 channel negotiation failed

I'm trying to connect with MQ service and for ssl connection imported my certificate in cacerts file.
But when I'm running to connect, its showing below error
rc=2059 amq9503 channel negotiation failed
Do I need to create separate keystore and place my certificate in it, then point it using parameter javax.net.ssl.truststore ?
MQ error 2059 (MQRC_Q_MGR_NOT_AVAILABLE) has nothing to do with SSL.
This error means usually means you are missing a client-side SSL certificate.
# Check your certificate installation path
javax.net.ssl.keyStore=<path to key store containing just your client certificate>
javax.net.ssl.keyStorePassword=<password for that key store>

WebLogic Hostname verification problems

I have the following setup using Weblogic 12c on a Centos8 server:
There is one domain, that consists of two machines (machine0 and machine1).
Nodemanager is configured for both, and the admin console also tells me, that both nodemanagers are reachable. Both of the machines ip adresses are set in the /etc/hosts file to machine0 and machine1.
Hostname verification is disabled in the admin server, as well as in the nodemanager's properties files. So far so good.
Furthermore I'm using custom certificates in two jks stores (ID nd Trust) which have been verified to work in a different scenario (just using localhost in two "machines").
Now I create a new managed server via the admin console (doesn't matter for which machine) with hostname verification turned OFF in the SSL tab (all other necessary SSL settings are valid).
If I try to start it right after creation via the admin console (nodemanager is reachable!) the server log tells me:
<BEA-090960> <The server's SSL configuration is not available. There will potentially be SSL handshake failures.>
<BEA-090924> <JSSE has been selected by default, since the SSLMBean is not available.>
<Security> <BEA-090908> <Using the default WebLogic SSL Hostname Verifier implementation.>
Leading to:
<Info> <Management> <BEA-141298> <Could not register with the Administration Server: java.rmi.RemoteException: [Deployer:149150]An IOException occurred while reading the input.; nested exception is:
javax.net.ssl.SSLKeyException: Hostname verification failed: HostnameVerifier=weblogic.security.utils.SSLWLSHostnameVerifier,
But it also tells me, that it was able to load trusted certs from my defined Trust store:
<Security> <BEA-090169> <Loading trusted certificates from the jks keystore file /home/iffuw/Documents/keystores/TrustStore.jks.>
The only way to start the server right after creation and correct configuration in the described manner is to add this option to the "startWeblogic" script in the domain's /bin folder.
JAVA_OPTIONS="${JAVA_OPTIONS} -Dweblogic.security.SSL.ignoreHostnameVerification=true"
to disable hostname verification via a JVM argument.
Once the server booted up, I can comment out that line again, since ALL SSL settings seem to have taken effect now.
So it looks like all custom SSL settings (my custom ID and trust stores, otherwise no SSL connection to the AdminServer would be possible) are transferred at the first server start via admin console and nodemanager, but NOT the setting to ignore hostname verification.
Am I missing something here?

Using Java Mail StartTLS with a Truststore

I'm trying to connect to a mail server which uses StartTLS with a self signed certificate via Java mail API.
And that seems to be a problem, because i can't find any way to set accepted certificates or a truststore for StartTLS.
Properties props = new Properties();
props.put("mail.imap.starttls.enable", "true");
props.put("mail.imap.starttls.required", "true");
Session session = Session.getInstance(props);
Store store = session.getStore("imap");
store.connect(hostName, port, userName, userPassword);
When i run my application as is, i get this PKIX path error:
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
I would prefer not to use VM parameters like "-Djavax.net.ssl.trustStore" because i want to be able to control trusted certificates per access.
Sidenote: I've seen people use "mail.imap.socketFactory.class" to set their own implementation of SocketFactory with a self defined TrustManager.
But when i do that my connection fails with
javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?
I think this is because setting the socket factory will actually use SMTP over SSL instead of StartTLS (which starts as a plain text connection and switches to TLS later).
I have this working for an SMTP connection (not IMAP) using com.sun.mail:javax.mail:1.5.5 and (root) certificates loaded from a (not so standard) pfx-file. The properties given to Session.getInstance(props) are build in the following manner (see also the API-docs here and here, I think you can simply replace smtp with imap for most of the properties):
"mail.transport.protocol", "smtp"
"mail.smtp.host", "hostname"
"mail.smtp.port", "25"
"mail.smtp.connecttimeout", "5000" // 5 seconds
"mail.smtp.timeout", "50000" // 50 seconds
"mail.smtp.ssl.protocols", "TLSv1.2"
"mail.smtp.starttls.required", "true"
Now build a SSL Socket Factory using com.sun.mail.util.MailSSLSocketFactory (read the API-docs in the link):
MailSSLSocketFactory sslSocketFactory = new MailSSLSocketFactory("TLSv1.2");
Create and intialize a (default) KeyManagerFactory kmf (e.g. by loading a keystore).
Create and intialize a (default) TrustManagerFactory tmf.
Call sslSocketFactory.setKeyManagers(kmf.getKeyManagers()) and sslSocketFactory.setTrustManagers(tmf.getTrustManagers())
Set property "mail.smtp.ssl.socketFactory" to the sslSocketFactory instance (use the props.put(k,v)-method). Note that the socket factory instance that was created and configured is set, not some String or class. Javamail will use the set socket factory instance directly.
Use the properties to create a session.
Make sure you have logging configured properly and set it to TRACE for com.sun.mail. Logging shows exactly what is "going over the line" and in my case shows for example:
DEBUG com.sun.mail.smtp - Found extension "STARTTLS", arg ""
...
TRACE com.sun.mail.smtp.protocol - STARTTLS
TRACE com.sun.mail.smtp.protocol - 220 Ready to start TLS
On a side note: creating a default keystore and trustore can be done using this SslUtils class, methods loadKeyStore(null) and createDefaultTrustStore() (I created this utility class a while ago to help me load the not-so-standard pfx-files).

Java mail TLS authentcation

I am trying to get a grasp on the fundamentals of Java Mail API and TLS. I have the following scenario:
There is an STMP server that uses TLS & SSL. If I log on to this server with some client, I can send authenticated &verified e-mails without any problems.
Then I try to run a web server on a different machine, that sends mail using the previously mentioned SMTP server. I still want to send TLS & SSL emails, however no matter how I configure the startup properties I get the following well known error:
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
I found a lot of people having similar issues, however my question is this:
Considering the previuosly described scenario, do I have to get some kind of certificate to the web server (possible somewhere in the JRE), or should it just work fine since the mail server already has that certificate & authentication mechanizm running. Shouldn't it be possible to just use the certificate of the SMTP server? Anyway, if I have to install the certificate to the machine that uses the STMP server how can I get that certificate?
I'm pretty new to JavaMail API and I have seen lots of articles about this but I could not find the answer black & white for my question.
Your client (that is in your case the one running on the webserver) needs to verify the SSL certificate of the mail server. It seems that your java truststore doesn't contain that certificate.
So you either need to put that certificate into the default truststore of your JRE (what I wouldn't recommend) or define a different truststore for your application (that of course needs to contain the mail servers certificate). To do that set this VM parameter: Djavax.net.ssl.trustStore=<path-to-truststore>
Edit: Ah I missed some part of your question.
To get the certificate of the mail server use something like openssl. See for example:
https://serverfault.com/questions/139728/how-to-download-ssl-certificate-from-a-website
The answer is in the JavaMail FAQ.
Quoted text from the linked site:
Q: When connecting to my mail server over SSL I get an exception like "unable to find valid certification path to requested target".
A: Your server is probably using a test certificate or self-signed certificate instead of a certificate signed by a commercial Certificate Authority. You'll need to install the server's certificate into your trust store. The InstallCert program will help.
Alternatively, you can set the "mail.protocol.ssl.trust" property to the host name of your mail server. See the javadocs for the protocol provider packages for details.
Other common causes of this problem are:
There's a firewall or anti-virus program intercepting your request.
There's something wrong in your JDK installation preventing it from finding the certificates for the trusted certificate authorities.
You're running in an application server that has overridden the JDK's list of trusted certificate authorities.

SSL client - when is the certificate needed?

I have this:
SSLSocketFactory factory = HttpsURLConnection.getDefaultSSLSocketFactory();
SSLSocket socket = (SSLSocket) factory.createSocket("www.verisign.com", 443);
This is failing on the 2nd line with a "Connection refused" error.
Now, would I have to install verisign's certificate in my trust store before I can even do the above? I was under the impression that I could connect to an SSL server and execute getPeerCertificates() to get the certificates. Is this not what our browsers do? Otherwise how would they know which signing authority to use?
(Obviously I'm using Verisign as an example. My real URL is far too fugly to use here...)
Connection refused means nothing was listening at the target host:port, or a firewall got in the way. This is logically and temporally prior to anything SSL does.
Have you checked that the remote service is actually up and running, and that you can connect to it? Perhaps the "Connection refused" error is actually a refused connection. :-)
Usually you don't need to install server's certificate on your computer explicitly. PKI works in the way that your system should be able to validate server's certificate without any prior knowledge about it. However this will work only when your server's certificate has it's roots in on of the "known CAs", i.e. certificate authorities, whose root or other certificates are already listed on the client system. If this is not the case (eg. you have a self-signed or some other custom certificate on the server), you really need to install the certificate on your client system before the mentioned classes can validate server certificate properly.
You can read about certificates and how they are used in SSL here.

Categories