OkHttp client certificate without intermediaries - okhttp

I'm trying to use okhttp to authenticate to a server.
With curl it would be done this way:
curl \
--cert certificate.cer \
--key private-key.pkcs8 \
"https://some-url"
Unfortunately, okhttp-tls appears to always expect a chain of certificates in addition to the held certificate, which isn't something I have.
heldCertificate expects the chain of certificates, in addition to the clientCertificate, contrary to the example provided in the reame:
HandshakeCertificates clientCertificates = new HandshakeCertificates.Builder()
.addTrustedCertificate(rootCertificate.certificate())
.heldCertificate(clientCertificate) // <--------------------
.build();
How can I use okhttp with a single certificate and my private key?

heldCertificates expects a chain of intermediates that may exist between the client certificate (matching the private key) and up to but not including the root CA that the server is known to trust. So this could be left out if no other certificates are required.
See https://square.github.io/okhttp/4.x/okhttp-tls/okhttp3.tls/-handshake-certificates/-builder/held-certificate/
Configure the certificate chain to use when being authenticated. The
first certificate is the held certificate, further certificates are
included in the handshake so the peer can build a trusted path to a
trusted root certificate.
The chain should include all intermediate certificates but does not
need the root certificate that we expect to be known by the remote
peer. The peer already has that certificate so transmitting it is
unnecessary.
Here are some examples for using a self-signed certificate if known to be trusted already by the server, and also for switching the key used based on the host being connected to. You will need to adapt these based on your exact setup, but they should give you a starting point to test with.
https://github.com/square/okhttp/pull/6470/files

Related

Make a certificate for testing purposes but NOT self signed

I want to have a certificate that has a different CA cert for it.
Reason? - For self signed certs, most browsers handle this as a invalid certificate. I know I can ignore those warnings but I just don't want to get them in the first place.
I tried googling how to create such a certificate but found so many sites where only a self signed certificate is created.
Therefore, how can such a certificate + CA certificate be generated and is there a better synonym for such a certificate pair?
If you need certificate signed by trusted CA there are two options:
You can get free letstencrypt certificate.
This certificate will work everywhere, not only your testing machine.
To get such certificate you need to own (e.g. buy) some domain, so you can pass certbot ownership challenge.
If you need to test local server, you can get certificate for subdomain (e.g. local-test.example.com is subdomain of example.com) and map that subdomain to 127.0.0.1 in /etc/hosts.
For purpose of local testing, certificate signed by self-signed CA can be sufficient.
Google Chrome and most other applications will accepts such certificate after you install/trust your self-signed CA (some applications may require restart).
There are some convenient tools written in go and js.

Understanding elasticsearch certificate

I saw there are two type of certificate which is elastic-stack-ca.p12 and elastic-certificates.p12. What are the differences between these two certificate.
https://www.elastic.co/guide/en/elasticsearch/reference/current/security-basic-setup.html#generate-certificates
Also I noticed we have HTTP certificate
https://www.elastic.co/guide/en/elasticsearch/reference/current/security-basic-setup-https.html#encrypt-http-communication
why there are so many certificate.
If I want to send data from beats which certificate should be used? I saw it need .cer and .key
can someone help me to understand this.
You need both, and each one has a specific role.
***ca.p12 is the certificate to the new Certificate Autohirity which is created since Elastic certificated is auto assigned.
***certificate.p12 is the certificate to each single instance of your elasticsearch cluster.
I would recommend you to follow the steps here https://www.elastic.co/guide/en/elasticsearch/reference/current/security-basic-setup.html
Source:
https://www.elastic.co/guide/en/elasticsearch/reference/current/certutil.html#certutil-ca
ca.p12 -> CA Mode
The ca mode generates a new certificate authority (CA). By default, it produces a single PKCS#12 output file, which holds the CA certificate and the private key for the CA. If you specify the --pem parameter, the command generates a zip file, which contains the certificate and private key in PEM format.
certificates.p12 -> Cert Mode
The cert mode generates X.509 certificates and private keys. By default, it produces a single certificate and key for use on a single instance.
To generate certificates and keys for multiple instances, specify the --multiple parameter, which prompts you for details about each instance. Alternatively, you can use the --in parameter to specify a YAML file that contains details about the instances.

Git-For-Windows not reading my self-signed SSL certificate

I deploy my CA cert via GPO into Trusted Root Certification Authorities, which I can see is deployed to my client machines. I know this part is working as Chrome no longer moans when browsing to sites using my signed SSL certs.
However, when I try and git clone or push to any repositories behind an SSL cert signed by this CA, git-for-windows bawlks and says this:
schannel: next InitializeSecurityContext failed: Unknown error
(0x80092012) - The revocation function was unable to check revocation
for the certificate.
As you can see, I've got schannel enabled, but git-for-windows is clearly not reading my CA cert from the Certificate Store in Windows. Any one know how I make gfw read from the Certificate Store in Windows? I can't manually copy this cert onto all my Windows clients, that'd take forever.
Perhaps worth noting I'm using multiple Samba 4 instances as Domain Controllers, but I don't have access to Windows Server tools such as AS Certificate Services.
nb. I know I can disable tls verification, but that surely defeats the purpose.

Self-Signed Certificates in Spring-Boot

I'm trying to get a Spring-Boot server up and running, which provides some security via SSL. I followed steps 1 and 2 of this guide to get a self-signed certificate and am able to access my site via https. The application.properties looks like this:
server.port=8443
server.ssl.keyStore=classpath:keystore.p12
server.ssl.keyStorePassword=youd_want_to_know
server.ssl.keyStoreType=PKCS12
server.ssl.keyAlias=hs
keystore.p12 was generated with
$ keytool -genkey -alias hs -storetype PKCS12 \
-keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 3650
Except for the password I didn't enter anything, all fields are "Unknown".
However, the lock in the browser isn't green. The detail message says
There are issues with the site's certificate chain (net::ERR_CERT_AUTHORITY_INVALID).
The plus-side:
Secure TLS connection
The connection to this site is using a strong protocol version and cipher suite.
Secure Resources
All resources on this page are served securely.
I guess in plain text it means that the data is transported securely, but the browser isn't fully happy with the certificate in terms of it can't track the authenticity. Therefore, I understand that this isn't worthy for production (and for now it doesn't need to be).
But, is it safe and secure for me since I own the server and know that I created the self-signed certificate myself? Or are there ways to turn this into a certificate that the browser is happy with? What do I need to do to make that work and what would the Sprint-Boot configuration look like?
Thats how the browser is supposed to behave. As long as you (or rather, browsers you or your organization owns) are the only consumers of your website, you are fine. But once you want to on-board other consumers you might need to get your certificate signed by a certificate provider
In this case the communication between browser and server is still vulnerable to man-in-the-middle attack, so this not really "secure & safe"
In a Nutshell,
Using a self signed certificate is completely unsafe unless
you control every machine between you and the server
OR
you check that the keys in the certificate are what you expect them
to be.
Only advantage is; it will block passive attacks (the attacker observes the data but does not alter it in any way) regardless of whether the CA certificate was issued by a mainstream CA or not.
Take a look here https://security.stackexchange.com/a/8112

How to configure Tomcat (in Spring Boot) to provide full certificate chain with SSL connections? (currently working with Chromium, not with Firefox)

I have the following issue: I have a domain that hosts a) a website on port 443 (Apache) and b) a web app with Spring Boot (Tomcat) on port 8443. Both are using the same certificates. For Tomcat I generated a keystore that consists of the private key/certificate, intermediate and root certificate. Visiting the website is not an issue at all.
Now, when I visit the webapp from e.g. Chromium or from my smartphone I can access it and https works just fine (certificate is trusted and I can view the certificate chain). If I instead try opening it in Firefox or use openssl s_client -connect domain.com:8443 the connection is not secured and only my certificate, but neither the intermediate and nor the root certificate are provided.
Now I don't understand how that happens, whether maybe Chrome recognizes the certificate chain from the issuer field of the certificate or asks the app server to provide further parts of the chain, and Firefox/openssl do not.
Any hint about how to make this running would be greatly appreciated!
BR Johannes
BTW about the keystore creation: I created an empty keystore, added the root, then the intermediate and then my certificate + key.
Seems I made a mistake on how to create the keystore, just importing the certificate chain and the key pair wasn't enough. I had to append the certificates of the chain to my certificate (using KeyStoreExplorer or as described in this answer.
How it came that Chromium accepted the certificate anyway is still a mistery to me, though.

Resources