I have 1) X509 Certificate (child) -> Authentication CA (parent) certificate and -> root CA (root) certificate.
Questions:
Can I retrieve this Authentication CA certificate from current X509Certificate certificate?
when I double click my certificate, I see the hierarchy of certificates. And from here, I can open each one. So, can I get Authentication CA certificate location or something like that from that certificate?
what ways can you recommend , in order to retrieve Authentication CA certificate?
I need to do this using java code. not key tool or something like that. I have Root CA certificate and X509 Certificate (child). and I need parent of child certificate.
I use bouncycastle and java's classes in order to work with certificates.
An X.509 certificate does not contain within it the certificate of the issuing CA. If you double-click on the child certificate and see a chain, this suggests that your operating system has access to the intermediate certificates (somehow).
If you need a chain of certificates, then you need to retrieve this from some external source. Many protocols (such as SSL) will provide a full certificate chain by default. The answer really depends upon the context of your problem, which is not clear from your question.
Related
UPDATE: After I have found a solution, I edited the question to be more clear for future reference.
I've got a corporate (ie not well known) CA certificate from a company which provides us a web services to be called from Java. I added this CA certificate to default cacerts trust store (keytool -import -file cert.cer -alias myca -keystore jre/lib/security/cacerts), but connection to the service still fails with the dreaded "PKIX path building failed" message. I have checked that issuer field of the end server certificate is the same as in the CA certificate and also validity dates is ok.
I don't know how to explain this. I can think of the following reasons but I don't know which one is true:
I have noticed that when I add also the end server certificate to trust store, the connection is OK. Maybe cacerts by design don't work as I expect (ie all the certificates signed by an authority added there are considered valid), but instead I have to add all the end server certificates to a trust store including CA certificate of their issuer.
I have to add CA certificate in some other way - by different command, to different file etc.
Maybe the CA certificate is not correct and keytool refuses to consider it a certificate authority.
Maybe PKIX path building fails for other reason.
How can I debug this problem more to find an answer?
Details:
The end server certificate is wildcard certificate
There is no intermediate certificate, just root and the end certificate
I was facing the same problem with "PKIX path building failed" with Let's Encrypt signed certificates at a time Java didn't incorporate the Let's encrypt CA certificate in its default trust store.
My story is written in detail here: http://blog.novoj.net/2016/02/29/how-to-make-apache-httpclient-trust-lets-encrypt-certificate-authority/
At the end I was able to make Java trust "the end of the chain" server certificate by creating internal trust store embedded in my application that contains only root CA certificate (and the backup one).
I much more prefer creating internal application truststore than importing certificate in main Java trust store for two reasons:
you don't need another extra step in install procedure for initializing the global trust store
you limit "the trust" to you application and don't affect another applications running on the same JVM (or better you can even limit the trust to the certain instances of client objects in your application if required)
Maybe I had a different scenario than you're facing, so downvote me if I didn't get the point.
The trust store needs to contain the root certificate (the CA's cert).
I'm not sure if that's what you mean by "the last one I'm the chain", but the CA certificate should be the last one in the certificate chain presented by the server.
If your certificate is signed by a well-known CA, then the CA cert should be in the trust store, and if the server's certificate chain is set up properly, everything should just work.
If yours is a self-signed certificate, then the root certificate will not be in the trust store, and you will have to add it.
Thanks to #pedrofb comment I found out that the reason PKIX path fails is simply that the CA certificate I got is not the CA that signed the end certificate. What made it so complicated is the monstrous incompetence of company that gave me the CA certificate which obviously has two CAs with almost the same description (cn, o, st, c) which differs only in SN and which both issued the same wildcard certificate. Only after I became super paranoid and compared the SNs, I understood the problem.
After tons of search, I didn't find how to make equivalent of following command in Java code :
openssl pkcs12 -cacerts -in /path/to/file.p12 -noout
to get only ca certificates from this p12 or
openssl pkcs12 -clcerts -in /path/to/file.p12 -noout
to get the certificate
In java, I load file.p12 so all this certificates are stored in the PKCS12 keystore but cannot differentiate which is CA cert and which is simple cert. How to do that ?
(In my p12, I have my certificate and N CA certificate which have signed it :
CA 2 has signed the certificate, CA 3 has signed the CA 2 certificates ..., CA N has signed the CA N-1 certificates)
2) Another question in the same way :
is there a way to order x509 certificate list to obtain (ca 1, ... ca N), I used :
CertificateFactory certFact = CertificateFactory.getInstance("X.509");
CertPath path = certFact.generateCertPath(myCertifList);
But the list need to be already ordered contrary to what I hoped.
3) Is fullchain certificates order guaranteed ? What if Let's Encrypt for example change its strategy and change way to build chain and fullchain in the way we can't rely on actual cert order ?
Thank you very much for help !
The practical way a P12 is issued is: with a single PrivateKey and corresponding Certificate Chain (general internet standard).
You can read more about this in these links: PKCS#12, Chain of Trust and Intermedial CA.
Usually (almost all the time), the user's certificate will be the first certificate (most important) in the chain, followed by the least important ones (Sub CA's and CA's, CA being the last).
Almost all the softwares and libraries out there follow this approach.
So, it is safe to say that the certificate chain will be ordered (however, there is possibility that the chain may not be complete, you could only have user's certificate, or the CA certificate might not be there after the Sub CA's certificate. This highly depends on the CA that issued the P12/Certificate chain). But, you will find the user's certificate at the first (zeroth) position.
If you need to make sure that the chain is complete and ordered you can have your own defensive method that does this. You can identify the type of certificate (CA, SubCA or user) based on the SubjectDN and the IssuerDN fields of the certificate.
If the SubjectDN equals IssuerDN, then it is a CA certificate, and then identify the next certificate (SubCA), if the certificate's IssuerDN is equal to SubjectDN of the CA, then it is the next in the chain, and so on..
SSL certs never ends to dazzle me. I have an web-app and it makes a rest call to another service from a partner to fetch certain data. They use a self sign'ed or an internal CA generated for the Company. The issue is whenever the other end updates there SSL cert, my app fails. This is because the public cert (.cer) that i downloaded from their website and imported in the java trustore of my app doesn't match with their new site. To fix this, i have to re-download their latest public server cert and import again to my java trust store.
Assuming that they use a consistent ROOT CA or an intermediate CA cert to sign their ever changing SSL certs, can i just import the ROOT CA or the INTERMEDIATE CA once and for in my java trust store all to deal with this? So, as long as they don't change the ROOT CA or the INTERMEDIATE CA, my app will be able to make the call.
So their self signed CERT is not built from ROOT CA. Their CERT they generated themselves, so that is why it is considered untrustworthy by default. So every time they generate a new one, this is what happens:
Your app says hello to their server
Their server sends the newly generated CERT which includes information like: Public key, algorithm, cert valid date range, etc.
Your app gets the new CERT and compares it with the old CERT and realizes, oh, these are not the same.
Your app says, well, this is not trustworthy and throws an error.
This is by design because this would be similar to the same result of a man-in-the-middle attack. Your client only trusts certain CAs for that reason. The job of a CA is to certify against certs to see if they are good or bad. If you can add certs on the fly like that without the CA's knowledge, then the CA really has no idea which certs to trust.
So there could be an intermediate Certificate Authority that this company has opened up to you or that they have worked with to provide to you. You would have to ask them to see if they are using some kind of CA at all that you could connect to.
I doubt this the case because you said they are using "self-signed" certs which implies that they are not working with any CA.
I have a certificate for a Glassfish server within a Java keystore. It has a 4part certificate chain, which I can see with the list command. Now one of the intermediate CA certificates has been revoked and I have to change the chain of my certificate, because it is now untrusted.
In the Windows IIS I have added the new intermediate certificate to the certificate store and all was fine. For the Java keystore I have no idea how I could do that? Should I export the certificate incl. the chain as PEM and replace the text parts for the intermediate CA? The CA says, I don't have to use a new certificate, it is only necessary to correct the chain, so it makes no sense to generate a new certificate request.
Any ideas?
I have an instance of X509Certificate in java and I need to check if the issuer is trusted?
thanks
gal
If you just have the certificate (out of context), you should build a certification path using the Java PKI Cert. Path API. If it's within the context of SSL, you should be able to use a TrustManager and check it when using your SSLContext.
This will verify whether the certificate was issued by a CA you trust (or via one of its intermediate CAs perhaps).
You may also be interested in "What data should I validate when validating X.509 certificates using Java?" (on Security.SE).