How to configure SSL in Jetty with CA signed certificate properly? - ssl

I am trying to secure my eXist-db app, which means the only port I want to leave open should be 8443 (for using WebDAV and admin app). This is the basic secure port eXist-db have open since the installation. It uses self-signed certificate. I have no problem with replacing default certificate with a new one but the problem is I am not able to do that with CA signed certificate.
I tried:
sudo rm eXist-db/tools/jetty/etc/keystore
cat ServerCertificate.crt Alpiro-TrustProvider-IntermediateCA.crt Root.cer > cert-chain.txt
I cleaned bad ends of lines and verified every certificate starts on a new line.
openssl pkcs12 -export -inkey my-app.key -in cert-chain.txt -out my-app.pkcs12
keytool -importkeystore -srckeystore my-app.pkcs12 -srcstoretype PKCS12 -destkeystore eXist-db/tools/jetty/etc/keystore
After restart, I checked the connection with: openssl s_client -connect xx.xx.xxx.xxx:8443 and everything seems fine. I can see there is my trusted certificate and the connection (handshake) simply works. However, browsers still claim it is not a trusted connection.
When I try to check something over https via XQuery, it throws:
java.security.cert.CertificateException: No subject alternative names matching IP address xx.xx.xxx.xxx found …

The solution is quite trivial. The problem was I had been trying to access the site via IP, not via fully qualified domain name. Certificates are associated with domain names, not IPs!

Related

acivemq, secure websockets, CA, security and same origin restrictions - How do I install a CA certificate?

Has anyone managed to install a CA certificate into an activemq instance? I've been doing google searches and reading the activemq documentation but I haven't found anything on how to use a pre-existing CA certificate in activemq.
I assume I install it into the activemq keystore. Is that correct? I'll be using it with websockets and mqtt on the client end.
Also, just in case my assumptions are incorrect, here's why I think I need to use my current CA certificate.
1) I have a web application and our users require communication with the server to be secure. All http traffic is secure.
2) All modern web browsers have a same-origin policy for websockets. They also seem to have a no-mixed-content policy. And so because my http traffic is secure I also have to use secure websockets. (I also have to run the activemq server at the same url)
I'd rather not tunnel the websocket traffic over http because then I have to worry about the apache configuration in addition to the activemq configuration - just another place for things to potentially go wrong.
Also, I don't transfer any sensitive information over the websocket so I could potentially leave it unsecured, but first, my users probably wouldn't understand that, but also it looks like browsers have a no-mixed-content policy.
Has anyone gone through what I'm going through? Any tips?
I eventually got this working, but ultimately I decided to tunnel my websockets communication through apache using the ws_tunnel module.
But to answer my question above, basically what you have to do is create a new java keystore based on your webserver keys, and then replace the apachemq java keystore with this new keystore. I was never able to successfully import the keys into the existing keystore.
For example, on my ubuntu server, my keys are:
SSLCertificateFile /etc/apache2/ssl/star_astracorp_com.crt
SSLCertificateKeyFile /etc/apache2/ssl/star_astracorp_com.key
SSLCertificateChainFile /etc/apache2/ssl/astracorp.com.intermediate.sha1.chcrt
I then export the key as pkcs12:
openssl pkcs12 -export -in /etc/apache2/ssl/star_astracorp_com.crt -inkey /etc/apache2/ssl/star_astracorp_com.key -out server.p12 -name emsu1 -CAfile ca.crt -caname root
I then import the pkcs12 into a new java keystore:
keytool -importkeystore -deststorepass password -destkeypass password -destkeystore server.keystore -srckeystore /etc/apache2/ssl/server.p12 -srcstoretype PKCS12 -srcstorepass password -alias emsu1
Then, in my apachemq directory I move the old broker.ks out of the way and rename server.keystore as kroker.ks and restart activemq.
One of my servers had .pem files for its keys. The process was still similar, however I had to go into OS X's keystore utility to get the password of the key.
openssl pkcs12 -export -in /etc/certificates/ems-dev.local.EDA65671FF2C9CE7DAA56E9AD8E4E5F3F2675C79.cert.pem -inkey /etc/certificates/ems-dev.local.EDA65671FF2C9CE7DAA56E9AD8E4E5F3F2675C79.key.pem -out server.p12 -name emsdev -CAfile ca.crt -caname root
you will then be asked for the key - copy and paste it from the key util.
Then, the process to create a new keystore is the same:
keytool -importkeystore -deststorepass password -destkeypass password -destkeystore server.keystore -srckeystore /etc/certificates/server.p12 -srcstoretype PKCS12 -srcstorepass password -alias emsdev

How do I configure a Dropwizard application with intermediate certificate?

The Dropwizard example project has a single certificate without intermediate certificate and the HTTPS configuration doesn't mention anything regarding intermediate certs. Is it possible to configure Dropwizard to deliver intermediate certificates?
You should be able to add the intermediate certificate to the key store that you use for your certificate. To do that when you add the private key you should be able to add a chain of the signed public key with the intermediate certificate. The intermediate certificates should not be added by them selves The intermediate certificate should then also be sent to the client.
Dropwizard uses Jetty 9. From the Jetty 9 documentation:
If you have a chain of certificates, because your CA is an
intermediary, build the PKCS12 file as follows:
$ cat example.crt intermediate.crt [intermediate2.crt] ... rootCA.crt > cert-chain.txt
$ openssl pkcs12 -export -inkey example.key -in cert-chain.txt -out example.pkcs12
The order of certificates must be from server to rootCA, as per
RFC2246 section 7.4.2.
I would not include the root CA in the chain because it should be already known to the client.
OpenSSL will ask for an export password. Enter something and remember it for the configuration. The documentation includes further steps to convert the PKCS12 keystore to a JKS one, but that’s not required (PKCS12 works fine on Java 8u261).
Then configure the connector in your Dropwizard configuration file with the filename and password you used:
server:
applicationConnectors:
- type: h2c
port: 80
- type: h2
jceProvider: Conscrypt
port: 443
keyStorePath: example.pkcs12
keyStorePassword: foo
You can verify your configuration using OpenSSL:
openssl s_client -connect localhost:443
The section Certificate chain should show entries for your server certificate and the intermediate CAs.

Configuring Jenkins with StartSSL - adding the issuer chain

I am unable to correctly configure Jenkins to use a StartSSL certificate.
I'm running it with command line arguments that specify paths to the private key and my certificate as shown on the Jenkins Wiki (at the bottom: https://wiki.jenkins-ci.org/display/JENKINS/Starting+and+Accessing+Jenkins).
I've obtained a private key and a certificate from StartSSL
I've placed them in a particular folder
I'm running Jenkins as follows: java -jar jenkins.war --httpPort=-1 --httpsPort=8080 --httpsCertificate=<mydomain.crt file> --httpsPrivateKey=<my private key file>
Jenkins starts successfully. Opening https://mydomain:8080/ in Firefox says that the connection is untrusted:
mydomain:8080 uses an invalid security certificate.
The certificate is not trusted because no issuer chain was provided.
(Error code: sec_error_unknown_issuer)
I've tried verifying mydomain:8080 on various SSL checker websites:
OK mydomain resolves to xxx.xxx.xxx.xxx
OK The certificate was issued by StartCom.
OK The certificate will expire in XXX days.
OK The hostname (mydomain) is correctly listed in the certificate.
Not OK The certificate is not trusted in all web browsers.
You may need to install an Intermediate/chain certificate
to link it to a trusted root certificate.
StartSSL does not have explicit instructions for setting up Jenkins. I've tried following up on similar tutorials for other kinds of servers, and copied the intermediate authority files from StartCom into a unified certificate (ca.pem and sub.class1.server.ca.pem as noted here: http://www.startssl.com/?app=42).
However, this did not change anything.
SSL checkers like www.sslshopper.com/ssl-checker.html‎ still report that the website is untrusted.
Also, the GitHub image caching service is not rendering the build status icon from Jenkins for the same reason.
How do I add the issuer chain correctly to my certificate?
I had a similar problem and after some research what got everything to be trusted was :
Merged the intermediate authority certificate and <mydomain.crt file> into 1 unified certificate called merged.cer using the link you mentioned
(From: https://serverfault.com/questions/569866/jenkins-wont-serve-with-ca-signed-certificate)
openssl pkcs12 -inkey /location/to/key.pem -in /location/to/merged.cer -export -out keys.pkcs12
keytool -importkeystore -srckeystore keys.pkcs12 -srcstoretype pkcs12 -destkeystore jenkins.jks
NOTE: the key to use for the merged.cer should be the same as <my private key file>
Then follow the Jenkins Wiki to use the KeyStore instead of the certificate
java -jar jenkins.war --httpPort=-1 --httpsPort=8080 --httpsKeyStore=/path/to/jenkins.jks --httpsPrivateKey=<my private key file>

Two way authorization with PFX file

I have a problem with two-way authentication. I Use tomcat6 as a server and as a client I try IE, Firefox and my own java application.
The problem occurs using PFX certificates given to me by someone else. I have to use them as a client certificate, so i just add it to trusted certs on server and use it on browser in user certificates. The problem is that i get bad_certificate alert.
I have succeeded in doing two-way ssl by generating my own certificates for server and client and adding public keys as trusted in both keystores etc...
When i watch wireshark logs i see, that server sends good certificate request but client sends empty Certificate (11 bytes length packet) instead of 500+ bytes when i used my own generated cert.
What can be the problem? Why client does not send good cert? :(
Well, the first thing to check is to see if Tomcat is configured correctly to request a certificate from the client for the path in question. For Tomcat 6, this means you should have a Connector configured in conf/server.xml something like this:
<Connector port="443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
keystoreFile="${user.home}/.keystore" keystorePass="password"
truststoreFile="conf/truststore" truststorePass="password"
clientAuth="true" sslProtocol="TLS" />
The truststoreFile & truststorePass are important - if you just add "clientAuth=true" without including these two parameters, you'll see all sorts of strange behavior (and no warning that you did anything wrong). The truststoreFile must point to a legitimate JKS file that lists the CA's that you trust to sign the client certificates. If Tomcat is configured correctly, the browser should pop up a dialog to the user along the lines of: "The website requires a client certificate" along with a list of all certificates that have been imported to the browser. If you don't see this, there's something wrong with your Tomcat setup.
It sounds like you've got that set up correctly, but it's worth double-checking. Also, if you have it set up correctly, you will see a "certificate request" handshake message if you trace the connection in wireshark that lists the trusted CAs by distinguished name. Again, if you don't see this, check your Tomcat setup and most importantly the truststore.
The next thing would be to check the PKCS12 file itself. You can do this with:
openssl pkcs12 -in [path-to-pkcs12-file] -nokeys | openssl x509 -noout -subject -issuer
Make sure that the issuer's distinguished name matches one of the trustedCaCert entries in your trust store. This is sort of a hassle to do with the Java keytool, but you can double check using:
keytool -exportcert -keystore conf/truststore -alias [alias of trusted cert] | openssl x509 -noout -subject -inform der
If all of this checks out, but it's still not working, it's worth using openssl's s_client to troubleshoot, since you usually get a lot more troubleshooting information from it. To do so, you'll have to separate the key from the cert in the PKCS12 file:
openssl pkcs12 -in [PKCS12 file] -out [whatever].key
openssl s_client -tls1 -connect localhost:443 -cert [whatever].key -key [whatever].key
(You can use the same file for the "-cert" and "-key" argument because openssl is smart enough look for the "BEGIN CERTIFICATE" and "BEGIN RSA PRIVATE KEY" delimiters in the source files). I was having a frustrating problem with client certs that I couldn't figure out once until I used s_client and got a reminder that my client certificate had expired (which wasn't logged or output anywhere else).
Also, you might want to strongly consider shifting your configuration to use Apache over Tomcat - Apache is a lot more flexible, and gives you a lot more feedback when it comes to SSL confifguration than Tomcat is.
Take a closer look at your client certificates, in particular the X509v3 extensions "Key Usage" and "Extended Key Usage". They may be marked as not trusted for client authentication.
Using the openssl command-line tool:
$ openssl pkcs12 -in server-only.pfx -nokeys | openssl x509 -noout -purpose
Enter Import Password:
MAC verified OK
Certificate purposes:
SSL client : No
SSL client CA : No
SSL server : Yes
SSL server CA : No
This certificate is only signed for server authentication (normal HTTPS). For full details, use the -text option in openssl x509:
$ openssl pkcs12 -in server-only.pfx -nokeys | openssl x509 -noout -text
[..snip..]
X509v3 Key Usage:
Digital Signature, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Server Authentication
[..snip..]
If this is the case, you're going to have to ask to get a new signed certificate that is marked for client authentication use.

Client SSL authentication causing 403.7 error from IIS

I'm trying to connect to a web service (not under my control) configured to authenticate users via SSL client certs. I have a valid certificate in PKCS12 format containing the client certificate and associated private key. The certificate is issued by a CA accepted by the web service provider.
Installing the certificate and trying to access the restricted area in various browsers gives the following results:
IE6 - Works fine and I can retrieve the WSDL
IE7 - Prompts for the certificate but then fails with a 403.7 from the server
Firefox3 - Set to ask, but no prompt and fails with a 403.7
Safari 4 - Certificate is installed in the Keychain, but no prompt and a 403.7
Also, trying to access the web service programmatically (Java) fails with the same 403.7 error code.
Strange that this works in IE6 but in no other browser, what am I missing? Do I need to include the full CA certificate chain in the PKCS12 file?
Any help would be greatly appreciated.
This really works! If you're confused by the -inkey and -in options, they are the private key and certificate from the p12 file. You can convert the p12 file to pem format with:
openssl pkcs12 -in file.p12 -clcerts -out file.pem
and use the above command with "-in file.pem" only.
Also, you can import the root CA cert into your trusted certs store, here is the description how to do that: http://gagravarr.org/writing/openssl-certs/others.shtml#ca-openssl, and then you don't have to manually copy the certificates. After installing the cert use the command above without the "-CAfile chain.pem".
Ok, got this working. The answer is yes, I did need to include all intermediary CA certs in the PKCS12 file. I concatenated all the intermediary CA certs plus the Root CA cert in the file "chain.pem" then executed the following command:
openssl pkcs12 -export -chain -CAfile chain.pem -in cert.pem -inkey key.pem -out cert.p12