Chaining two certs with the same subject - ssl

I am trying to generate specific chain of certificate to use as certs for Corda node.
The certs structure is following
cert_0 -> Subject: Node DN (Legal identity cert)
cert_1 -> Subject: Node DN (Node CA cert)
cert_2 -> Subject: Doorman CA
cert_3 -> Subject: Network Root CA
I have generated all certs and then trying to chain them in two steps:
openssl pkcs12 -export -chain -CAfile nodedoormanrootca.pem -in identity-cert.pem -inkey identity-key.pem -out identity.p12 -name identity-private-key -passout pass:changeit
Step 1 works correctly and as the result I am getting certs bundle consisting of all 4 certs.
Next step is to export it to Java Keystore using keytool.
keytool -v -importkeystore -providerpath bcprov-jdk15on-1.66.jar -provider org.bouncycastle.jce.provider.BouncyCastleProvider -srckeystore identity.p12 -srcstoretype PKCS12 -destkeystore nodekeystore.jks -deststorepass changeit -srcstorepass changeit -alias "identity-private-key"
(I use Bouncy Castle provider because cert_0 uses ed25519 key)
The problem is that after keytool import I have only 1 entry identity-private-key without the rest of the chain.
The cause is that cert_0 and cert_1 have the same subject and keytool thinks that cert_0 is self-signed and thus stops after adding only first cert in the keystore.
So, any idea on how to create such chain of certs in JKS format where two certs will have the same subject (with different public key of course) ?
What comes in mind is to try create some small kotlin program based on Corda sources, but is there any easier solution? Maybe some hack for keytool or smth

There's some important aspects of this to be aware of as currently rolling your own certs isn't supported in certain kinds of corda networks.
if you're doing this on your own machine with a bootstrapped network I'd recommend against it as you can just use the bootstrapper's corda developer certificates.
If you're doing this for production or using your own PKI you should be able to do that with CENM (link here: https://docs.corda.net/docs/cenm/1.3/pki-tool.html)
There are no sample projects that demonstrate creating these certificates. However, if you download the Corda source code and look at X509Utilities.kt(https://github.com/corda/corda/blob/master/node-api/src/main/kotlin/net/corda/nodeapi/internal/crypto/X509Utilities.kt) and CertificatesUtils.kt (https://github.com/corda/corda/blob/master/node/src/main/kotlin/net/corda/node/utilities/CertificatesUtils.kt) you’ll find what is effectively a toolkit for creating certificates.
good luck !

Related

How do I create a usable certificate-store from several files

We have a process to request a signed cert from a CA and we get back 3 files:
cert.cer, cert.key, and cert.p12
I now need to build a valid/usable cert store from those files. I have copies of the CA & intermediate certs locally on my server. So I'm trying to import everything by using keytool. But I end up with a store full of about 100 certs plus the cert for my server. But when I try to use them I'm getting an error that the server cert is not valid unless the signing certs are also in the store. Basically there's no chain even though I the server cert says it was issued by the intermediate cert in the store. I use the following commands to import my certs and ca trusts.
keytool -v -importkeystore -srckeystore "cacerts.p12" -srcstorepass "$CA_PASS" -srcstoretype "pkcs12" -destkeystore "$KEYSTORE_NAME" -deststorepass "$STORE_PW" -deststoretype "jks";
keytool -importkeystore -v -srckeystore "$CERT_NAME.p12" -srcstorepass "$STORE_PW" -srcstoretype "pkcs12" -destkeystore "$KEYSTORE_NAME" -deststorepass "$STORE_PW" -deststoretype "jks";
I'm not sure what step I'm missing. This is an Ubuntu 20.04 server.
How do I create a usable certificate-store ..
Usable is the keyword here - what are you trying to use the keystore for? (usually - SSL, client authentication or WS-Security)
getting an error that the server cert is not valid unless the signing certs are also in the store
There are different files for different purpose:
cert.cer - a public key with a CA-signed certificate
cert.key - a private key
cert.p12 - a keystore, may contain the private key, may contain the public key with its certificate, usually contains both (private key, public key, certificate). So - better validate what does the p12 keystore really contain.
The PKCS#12 keystore usually can be used as it is, often no need to import into a separate JKS. However - depends on the software.
BTW - maybe you could get a keystore-explorer, an opensource gem software giving you a great overview when not understanding the details or cli options.
Basically there's no chain even though I the server cert says it was issued by the intermediate cert in the store
Depends on the usage, but the best practice is having the CA root or its intermediate certificates imported in the truststore.
To import a CA reply in the keytool, you simply import a CA reply (issued certificate) with the same alias name as its private key. I'm not sure if you can create a whole certificate chain this way, you may have a look at the mentioned keystore-explorer to be sure.

Create a self signed certificate for localhost and import it in Glassfish

I am developing a REST server that runs with Jersey on Glassfish, and I want to make it run on HTTPS on localhost.
I have found many tutorials for generating a CA cert, others for generating .cer / .crt / .key / .csr / ... files, others for generating a jks keystore.
But they do not answer my (very basic) question: how to generate a self signed certificate and use it in my app that runs on Glassfish, on localhost? From scratch to the integration for a real usage, without any prerequiresite having a crt, a jks or any other file.
(For information I use Linux)
Thanks
EDIT: I have finally created a certificate with the following commands
openssl req -x509 -out localhost.crt -keyout localhost.key \
-newkey rsa:2048 -nodes -sha256 \
-subj '/CN=localhost' -extensions EXT -config <( \
printf "[dn]\nCN=localhost\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:localhost\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth")
openssl pkcs12 -export -name localhostServerCert -in localhost.crt -inkey localhost.key -out localhostP12Keystore.p12
keytool -importkeystore -destkeystore localhostKeystore.jks -srckeystore localhostP12Keystore.p12 -srcstoretype pkcs12 -alias localhostServerCert
copy localhostKeystore.jks into /glassfish/domains/domain1/config
keytool -importkeystore -srckeystore localhostKeystore.jks -destkeystore keystore.jks
And I have modified http-listener-2 in the admin console with certificate nickname localhostServerCert, but I got an error page on https://localhost:8181 (ERR_CONNECTION_REFUSED)
EDIT 2 : I think there should be a problem with the certificate, since openssl s_client -showcerts -connect localhost:8181 returns no peer certificate available, No client certificate CA names sent
COMMON GOALS
It can be useful to run with SSL locally, and I like to start with real world URLs. This can also help you to think ahead to your production deployment design, which often involves a Private PKI these days, based on a self issued Root CA.
Web and API domains can sometimes be related these days, eg if an API issues secure cookies for the web origin. So for localhost development I first define URLs such as these:
https://api.mycompany.com
https://web.mycompany.com
DEVELOPER SETUP
Then add entries such as this to my hosts file:
127.0.0.1 localhost web.mycompany.com api.mycompany.com
:1 localhost
Then, in terms of certificates, I produce these deployable files:
Certificate
Filename
Usage
Root CA
mycompany.ca.pem
The root certificate authority that is trusted by the Java runtime
Wildcard Certificate
mycompany.ssl.p12
A password protected PKCS12 file deployed with the API
My Development Certificates Repository has an example of how to issue the certs using openssl, including a bash script you can use for your own domains. Essentially this is a Private PKI for a development computer.
CONFIGURING TRUST
You then just need to trust the Root CA in the Java runtime used by Glassfish. Personally I tend to avoid JKS files where possible, since they are specific to Java, whereas PKCS12 files are a more portable concept:
sudo "$JAVA_HOME/bin/keytool" -import -alias mycompanyroot -cacerts -file ~/Desktop/mycompany.ca.pem -storepass changeit -noprompt
FURTHER DEVELOPER SETUP INFO
These resources on a portable way to manage SSL development certs are provided below, which completes the architecture work:
My Developer SSL Blog Post
My Java API uses the above certs and loads the wildcard certificate via this code, where a P12 file is used as a keystore:
System.setProperty(
"server.ssl.key-store",
configuration.getApi().getSslCertificateFileName());
System.setProperty(
"server.ssl.key-store-password",
configuration.getApi().getSslCertificatePassword());
GLASSFISH
If Glassfish based setups mean the API itself does not load the PKCS12 file, then there may be a specific task to import the PKCS12 file. Many systems provide a GUI or API option for loading a PKCS12 file into a keystore. This may result in a command like this being run, which you can do manually if needed:
keytool -importkeystore -srckeystore mycompany.ssl.p12 -srcstoretype pkcs12 -destkeystore keystore.jks -deststoretype jks -v

Issue to install Geotrust certificate (SSL) on Tomcat

I got a certificate from Geotrust and I'm trying to apply it to my Tomcat web server, as can be seen in the image below, I left .csr and .p7b in the same directory (java / bin)
the softlayer support team, has indicated the link https://www.digicert.com/ssl-certificate-installation-tomcat.htm as help and when I execute the command I get the error:keytool error: java.lang.Exception: Input not an X.509 certificate
Anyone have been through this and can you help me? I've been trying to figure it out for days.
Reasons for the error :-
You are importing the certificate (p7b) in a wrong keystore . when you import the certificate in an existing keystore it will never ask you to punch in the password twice. If its asking you to punch in the password twice, it means its creating a new keystore. In a new keystore, you cannot import the the certificates as private entry You can only create Trusted Entry and add the certificates as trusted.
Solution
1)If you have the private key with you, please create a text file and rename the file as example.pem with all the certificates and private key in it in the below sequence
a) private key
b) Server certificate
c) Intermediate Certificate
d) Root Certificate.
2) Run the below openssl command
openssl pkcs12 -in example.pem -out certificate.pfx
3) As you have the pfx file from the above command, use the keytool command below to convert this in jks format for tomcat
keytool -importkeystore -srckeystore certificate.pfx -srcstoretype
pkcs12 -destkeystore certificate.jks -deststoretype jks.
4) Provide the certificate.jks directive in server.xml file of tomcat along with its password
5) Restart the tomcat service.
Hope this helps ..

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

Amazon AWS unable to validate thawte certificate chain

I just got an Thawte 123 SSL Certificate and have problems uploading it to AWS to use it with CloudFront as Custom SNI SSL Certificate. AWS refuses the CA Chain. I'm using the Thawte Intermediate CA bundle for SSL Web Server and Thawte Wildcard certificates.
To be able to use my private key I converted it to an RSA key with:
openssl rsa -in private.key -out private-rsa-key.pem`
And tried to upload it with:
aws iam upload-server-certificate --server-certificate-name example.com-certificate --certificate-body file://certificate.pem --private-key file://private.pem --certificate-chain https://search.thawte.com/library/VERISIGN/ALL_OTHER/thawte%20ca/SSL_CA_Bundle.pem --path /cloudfront/example.com/
Resulting in the following error:
A client error (MalformedCertificate) occurred when calling the UploadServerCertificate operation: Unable to validate certificate chain. The certificate chain must start with the immediate signing certificate, followed by any intermediaries in order. The index within the chain of the invalid certificate is: 0
Even Inserting the thawte_Primary_Root_CA.pem into the certificate chain as first immediate signing certificate, doesn't resolve the problem.
A client error (MalformedCertificate) occurred when calling the UploadServerCertificate operation: Unable to validate certificate chain. The certificate chain must start with the immediate signing certificate, followed by any intermediaries in order. The index within the chain of the invalid certificate is: 1
Is the Thawte CA Chain not compatible to AWS?
I am having the same issue right now, and tried everything.
Using SSL123 certificate (My rsa key and pem are ok)
I can't get to work the primary and secondary certs provided by Thawte, in any order.
I tried primary alone, secondary alone, primary+secondary, secondary+primary, also tried with the root cert and also tried with the primary&secondary from:
https://search.thawte.com/library/VERISIGN/ALL_OTHER/thawte%20ca/SSL123_SecondaryCA.pem
https://search.thawte.com/library/VERISIGN/ALL_OTHER/thawte%20ca/SSL123_PrimaryCA.pem
The only thing I can get from ELB is:
Unable to validate certificate chain. The certificate chain must start with the immediate signing certificate, followed by any intermediaries in order. The index within the chain of the invalid certificate is: 0
Where the index is not always -1, but also 0,1 and 2 depending on the order and the number of certs included.
[SOLVED FOR ME]
Apparently, the EC2 instance from which you create the certificate affects. I used a standard EBS instance with default AMI, and transformed the certificate provided by Thwate again, and it did work.
Here the steps:
CSR:
keytool -genkey -keysize 2048 -keyalg RSA -alias mycertificate -keystore keystore.jks
Once Thatwe responds: (Primary is the second certificate in the chain of the email).
Import the three certificates in the keystore.jks
keytool -import -alias Primary -trustcacerts -file Primary.crt -keystore keystore.jks
keytool -import -alias Secondary -trustcacerts -file Secondary.crt -keystore keystore.jks
keytool -import -alias mycertificate -trustcacerts -file mycertificate.cer -keystore keystore.jks
JSK > P12 - Transform keystore.jks into p12 format
keytool -importkeystore -srckeystore keystore.jsk -destkeystore keystore.p12 -srcstoretype jks -deststoretype pkcs12
P12 > PEM - Transform p12 format into pem format
openssl pkcs12 -in keystore.p12 -out keystore.pem -nodes
PEM > RSA PRIVATE KEY - Export the private key in RSA format
openssl rsa -in keystore.pem -text > keystore_rsa.pem
And it did work this time.
you must make sure that the certificate, private key, and certificate chain are all PEM-encoded as following:
-----BEGIN CERTIFICATE----- << -This is my Intermediate CA which signed my CSR
Base64-encoded certificate
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE----- << -This is my Root CA which signed my Intermediate CA
Base64-encoded certificate
-----END CERTIFICATE-----
You don't need to put your signed certificate in the chain.
Just add the intermediate and root ca in the Chain files should be enough.
Using the folliowing as ca chain certificate solves the problem:
https://ssltools.thawte.com/chainTester/webservice/validatecerts/certificate?certKey=issuer.intermediate.cert.57&fileName=thawte%20DV%20SSL%20CA%20-%20G2&fileExtension=txt
It is important to note that the intermediate certificates are not specific to your domain or certificate. So, every certificate issued that is like yours, has the exact same intermediate certificates.
You can think of them a bit like the routing number on your checks. The routing number is needed, but really says more about your bank than it does about you. Your account number, or your certificate in this case, is what is unique to you.
Because of the generic nature of the intermediate certificates there are websites like this one:
https://www.ssl2buy.com/wiki/ssl-intermediate-and-root-ca-bundle
That have all of the intermediate certificates pre-bundled (and in the correct order) for different certificate issuers.