Java keytool won't parse Extensions of my CA certificate - certificate

I'm currently creating an Android app, which is supposed to send a POST request to a server. Unfortunately, the server is using self-signed certificate. So I have to create a PKCS12 keystore, which will include the CA Certificate, and make my App use that keystore.
To create such a keystore, I'm currently using the command below:
keytool -import -trustcacerts -alias my-alias -file cacert.pem
-keystore mykeystorefile -storetype PKCS12
Unfortunately the keystore doesn't work. (Request fails on SSL handshake.)
When I inspected the keystore using this command:
keytool -list -v -keystore mykeystorefile
I noticed a strange line at the very end of this list.
#8: ObjectId: 2.5.29.18 Criticality=false
Unparseable IssuerAlternativeName extension due to
java.io.IOException: No data available in passed DER encoded value.
0000: 30 00 0.
*******************************************
*******************************************
Keytool failed to parse an extension, which is part of the CA certificate.
I tried the same for LetsEncrypt's CA certificates and it worked just fine.
I'd be glad for any pointers on how to approach and solve this problem.
Thanks.
Edit: Keytool I'm currently using is part of java-8-openjdk.
Edit2: So after inspecting the ca certificate, Issuer Alternative Name extension doesn't have any value. Wondering if there is a way how to skip that extensions?

There is no way to skip anything that's on a certificate.
If the Issuer Alternative Name is blank, whoever generated that certificate has generated it wrong. If it is a self-signed certificate, the Issuer Alternative Name and the Subject Alternative Name are the same value. If it is signed by any CA, the CA's Subject Alternative Name is put in the end user's Issuer Alternative Name.
You might need to ask them for the right CA certificate.

Related

How do I import a CSR reply back into my key-pair via command line?

I've created a keystore with an initial key-pair using keytool -genkeypair command, then generated the CSR using keytool -certreg command, then got it signed by our CA. Now that I got the CSR reply myCSRreply.cer, how do I incorporate the CSR reply with my original key-pair?
I've tried simply importing the CSR reply to my keystore using keytool -import command but that did not change my original key-pair. It simply added the CSR reply as another entry. I'm expecting it to change the issuer and thumbprint of my original key-pair.
I'm able to do what I want to achieve via KeyStore explorer as shown in the following screenshot but I need to know how to do this in command line.
If I tried importing where I specify the CSR reply file and the alias to my original key-pair, I'm getting the following error.
keytool error: java.lang.Exception: Failed to establish chain from
reply
The command I used to import CSR back into my key-pair that generated that error:
keytool -keystore myKeyStore.pfx -importcert -file myCSRreply.cer -alias mykeypair
Question
How do I import the CSR reply back into my key-pair via command line such that it's going to take the thumbprint and the issuer of the CSR reply as the new attributes of my original key-pair? (I'm just assuming this is the expected outcome because when I generate JWT using the private key that takes its thumbprint, authentication fails)
Is CSR reply really meant to alter the thumbprint and issuer attributes of the key-pair in which the CSR was generated from?
The command you're executing is fine. You don't have the complete certificate chain for the new certificate.
When you generated the mykeypair key pair, keytool wrapped mykeypair's public key in a self-signed certificate. (That's why you had to provide its expiration date and other details during generation.) As a result, it forms a complete certificate chain by itself; it's a root certificate. keytool always wants a complete certificate chain for every certificate.
When you attempt to import the CSR reply, you're importing a new certificate. At this time, keytool will try to build a certificate chain for it. keytool will search the key store and trust store until it reaches a trusted root certificate. If it can't do that, the import will fail.
Read the following documentation:
Import a Certificate for the CA
You now need to replace the self-signed certificate with a certificate chain, where each certificate in the chain authenticates the public key of the signer of the previous certificate in the chain, up to a root CA.
Before you import the certificate reply from a CA, you need one or more trusted certificates in your keystore or in the cacerts keystore file. See -importcert in Commands.
If the certificate reply is a certificate chain, then you need the top certificate of the chain. The root CA certificate that authenticates the public key of the CA.
If the certificate reply is a single certificate, then you need a certificate for the issuing CA (the one that signed it). If that certificate is not self-signed, then you need a certificate for its signer, and so on, up to a self-signed root CA certificate.
...
You import a certificate for two reasons: To add it to the list of trusted certificates, and to import a certificate reply received from a certificate authority (CA) as the result of submitting a Certificate Signing Request to that CA (see the -certreq option in Commands).
keytool Documentation

Difference between Entry Type "keyEntry" and "trustedCertEntry" in a keystore

I don't have much knowledge in this area, but i have still tried to do things by googling. Here is the problem i am facing.
Case 1(Works):
I have a CA signed certificate and i would like to use it in my Web Application. I first created a keystore. I see that it creates an entry type "keyEntry" in the keystore. Then i import the CA signed certificate to the keystore created.
Here are the steps:
keytool -genkeypair -keystore keystore.jks
I see an entry in the keystore of type "keyEntry" of alias "mykey"
Now i import the certificate:
keytool -importcert -alias abc -file cert.crt -keystore keystore.jks
Now i see another entry of trype "trustedcertEntry".
With this keystore i am able to access my web application when i uploaded it.
Case 2 (doesn't work):
I create a keystore on the fly while importing the certificate.
keytool -importcert -alias abc -file cert.crt -keystore keystore2.jks
Here i see only one entry type which is "trustedcertEntry"
With this keystore i am not able to access my web application.
Question:
What is key entry type "keyEntry" and "trustedcertEntry" and why does my keystore works only when i have the entry type "keyEntry"
My understanding of keytool is tenuous at best but I think the trick is that with Case 2, by omitting the -genkeypair, you're not generating the necessary private key.
In Case 1, the steps you're using are: create a private key pair (public key and private key), and then import a certificate into the trusted certificates for the keystore. Presumably you have another certificate in the keystore that's joining with the private key though it's possible the trusted cert is acting as the cert or your application isn't using a joined keypair/cert in the same file.
I can say that a 'trustedCertEntry' is a certificate which is trusted by the keystore. This is essential for allowing certificate chains (ex: Root-CA signs Intermediate-CA1 which signs End-Cert1. Without having both Root-CA and Intermediate-CA1 as trustedCertEntry, the keystore doesn't trust the end cert). TrustedCertEntry do not have private keys associated with them, only the public key the certificate contains.
A keyEntry (I think!) is a public/private key pair without the certificate.
A privateKeyEntry is a public/private key pair with an associated CA-signed or self-signed certificate.

Is it possible to generate CSR with long validity using Keytool

Is it possible to generate CSR with long validity using keytool?
When I generated CSR using the keytool command, I am always getting the validity only for 3 months.
Please let me know is there any way to generate CSR with longer validity.
Valid from: Thu Feb 13 17:34:07 EST 2014 until: Wed May 14 18:34:07 EDT 2014
Command used to generate Keystore is:
keytool -genkey -alias prodserver -keyalg RSA -keysize 2048 -keystore prodservermykeystore
keytool -certreq -keyalg RSA -alias prodserver -file prodservercertreq.csr -keystore prodservermykeystore
There are two types of certificates, self-signed and CA-signed.
The first command you have given generates a self-signed certificate. You can change the validity by specifying the -validity option to keytool. Depending on your need (internal testing, intranet app, ...) you may be able to stop here.
If you need to have a trusted CA generate a certificate then you will need to generate a CSR as in your second command to send to them. But a CSR does not have any way to specify the desired validity period, you need to communicate this separately to your CA when you send the CSR.
When the CA sends back your certificate you then import it into your keystore with the -importcert command to overwrite the previous prodserver entry.

How can I introduce a cross signing certificate into a chain?

I maintain a java applet that is locally deployed. I recently purchased a code signing certificate from Go Daddy (it was inexpensive, and they already host our site). My certificate chain is as follows (all files are available at https://certs.godaddy.com/anonymous/repository.pki):
my company
gdig2.cer
gdroot-g2.crt
Unfortunately, this root is not installed by default on Windows 7 (used by IE) or the Windows JRE (used by other browsers, I think). Manually installing the root certificate is doable, but it requires my users to have administrator access or run unfamiliar commands (it also doesn't make much sense from a security standpoint to say "you can trust my applet, and to prove it, run this command on your computer").
I would like to change my certificate chain to
my company
gdig2.cer
gdroot-g2_cross.crt
gd-class2-root.crt
which seems to be more prevalent (for example, it is the one in the Windows JRE, and is used to validate https://www.godaddy.com, which gets it into Windows 7). Go Daddy is not able to do this for me ("our support for using one of our Code Signing Certificates is limited"), so I'm left doing this on my own.
Following this answer, my most promising approach has been the following (on Mac OS X 10.6):
Convert my certificate into pem format:
$ openssl pkcs12 -in myCert.p12 -out myCert.pem -nodes
Use a text editor to open myCert.pem, delete gdroot-g2.crt, and paste in gdroot-g2_cross.crt and gd-class2-root.crt (openssl appears not to care about the order of the certificates, but I put them in the order shown above)
Convert the certificates back to p12 format:
$ openssl pkcs12 -export -in myCert.pem -out combined.p12
Unfortunately, this doesn't quite work. Calling
$ keytool -list -storetype pkcs12 -keystore combined.p12 -v
shows that my certificate chain extends through gdig2.cer, and stops. The problem appears to be that gdroot-g2_cross.cer doesn't certify gdig2.cer:
$ openssl verify -CAfile gd-class2-root.cer gdroot-g2_cross.cer
gdroot-g2_cross.cer: OK
$ cat gd-class2-root gdroot-g2_cross.cer > gdRootCross.pem
$ openssl verify -CAfile gdRootCross.pem gdig2.cer
gdig2.cer: /C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.com/repository//CN=Go Daddy Secure Certificate Authority - G2
error 20 at 0 depth lookup:unable to get local issuer certificate
But everything looks ok to me:
$ openssl x509 -in gdig2.cer -text -noout
. . .
Issuer: C=US, ST=Arizona, L=Scottsdale, O=GoDaddy.com, Inc., CN=Go Daddy Root Certificate Authority - G2
X509v3 Authority Key Identifier:
keyid:3A:9A:85:07:10:67:28:B6:EF:F6:BD:05:41:6E:20:C1:94:DA:0F:DE
. . .
$ openssl x509 -in gdroot-g2_cross.cer -text -noout
. . .
Subject: C=US, ST=Arizona, L=Scottsdale, O=GoDaddy.com, Inc., OU=https://certs.godaddy.com/repository/, CN=Go Daddy Root Certificate Authority - G2
X509v3 Subject Key Identifier:
3A:9A:85:07:10:67:28:B6:EF:F6:BD:05:41:6E:20:C1:94:DA:0F:DE
. . .
This leads me to think that I'm not using the cross certificate correctly, but I don't know what I'm doing wrong. (I've also tried appending the two new certificates to my original chain, to which openssl verify says error 18 at 0 depth lookup:self signed certificate.) I'm almost willing to believe that it's not possible to change the root certificate, but that seems to be the entire point of cross certificates. How can I introduce a cross certificate into my certificate chain in order to be verified by a different root certificate authority?
You don't. You just have one certificate signed by the first authority; and one certificate signed by the second authority - both are having the same public key / fingerprint and subject line. That's it.

How to convert .csr to .cer (or whatever usable on Windows)

I'm trying to figure out how to install .csr certificate under Windows but probably the only way is to convert it to some other format (maybe with openssl) but I have no idea how.
Do you have any suggestion?
CSR file is the Certificate Signing Request. It contains the information which is needed to generate a certificate based on your private key and information about the WebSite.
CER is the certificate itself (which you install into your Web browser). There is basically no way to convert directly from one to another as you need a key to sign the certificate, but what can do is to generate a self-signed certificate (e.g. certificate signed by the same key which was used to generate it):
openssl x509 -req -in server.csr -signkey server.key -out server.crt