https without client certificates

2,145 views
Skip to first unread message

laxman.v...@gmail.com

unread,
Apr 5, 2016, 6:33:56 PM4/5/16
to golang-nuts
Hi All,

In any browser, when a client sends a https request to WebServer(with self-Signed Certificate), Browser prompts with a warning message on whether to proceed or not.

Based on user acceptance, the certificate gets added in the browser certificate pool and doesnt get the warning next time requesting same https URL.

How does go client handle this?

I do not want to go with TLSClientConfig: &tls.Config{InsecureSkipVerify: true} option. I do not want to send the client certificates(self-generated) either (browser doesnt do this)

Is there any way to fetch the certificate received at tranport level from Server, add it to the cert pool and use this certificate while HTTPS GET.

Thanks & Regards,
L Vallandas

Lars Tørnes Hansen

unread,
Apr 6, 2016, 10:44:05 AM4/6/16
to golang-nuts, laxman.v...@gmail.com
>In any browser, when a client sends a https request to WebServer(with self-Signed Certificate), Browser prompts with a warning message on whether to proceed or not.

I think you mean a self-signed server certificate, true?
You can get a free certificate via Let's Encrypt: https://letsencrypt.org/. The browser does not issue a warning for a certificate from Let's Encrypt - if it hasn't expired.
Caddy server support Let's Encrypt: https://caddyserver.com/ - Caddy server is written in Go.

If you want authentication via a client certificate, you must store the public key from a client's certificate on the server.
After that you will of course need to configure your server to require a known client certificate in order to login..

/Lars

Manlio Perillo

unread,
Apr 6, 2016, 11:30:03 AM4/6/16
to golang-nuts, laxman.v...@gmail.com
Il giorno mercoledì 6 aprile 2016 00:33:56 UTC+2, laxman.v...@gmail.com ha scritto:
Hi All,

In any browser, when a client sends a https request to WebServer(with self-Signed Certificate), Browser prompts with a warning message on whether to proceed or not.

Based on user acceptance, the certificate gets added in the browser certificate pool and doesnt get the warning next time requesting same https URL.

How does go client handle this?



I have not tested the code, but you should do something like:

1) Connect to the HTTP server using a raw connection, by calling net.Dial
2) Convert plain connection to TLS connection by calling tls.Client
3) Call Handshake method on tls.Conn, and check return value

If handshake fails, get server certificates from ConnectionState and add them to your tls.Config; then connect to the server using http.Client.
If handshake succeed, connect to server using http.Client.

You must check TLS handshake for every new domain.


Regards  Manlio

laxman.v...@gmail.com

unread,
Apr 7, 2016, 5:27:40 AM4/7/16
to golang-nuts, laxman.v...@gmail.com

Hi Manlio,

Many Thanks.
This is what I exactly looking for and been trying.

No issue till the 3rd point. Got the response of ConnectionState but couldn't find a way in 'Go' to get the Server certificates and add them to tls.Config.

state := conn.ConnectionState()
for v := range state.PeerCertificates {
cert := &state.PeerCertificates[v]
}

transport := &http.Transport{
                        TLSClientConfig : tls.Config{Certificates: []tls.Certificate{}},}// get this cert

@Lars, I was trying for ssl connection in Go Client just the way a browser does. Browser has no control over server. When browser requests https server, client doesnt send its own certificate. Upon receiving the certificates from server as part of ssl handshake, if the user allows adds it to existing pool of certificate and client send these certificates in https Request to that specific server.

This was my understanding. Correct me in case am wrong.

Thanks
L Vallandas

Manlio Perillo

unread,
Apr 7, 2016, 7:58:17 AM4/7/16
to golang-nuts, laxman.v...@gmail.com
Il giorno giovedì 7 aprile 2016 11:27:40 UTC+2, laxman.v...@gmail.com ha scritto:

Hi Manlio,

Many Thanks.
This is what I exactly looking for and been trying.

No issue till the 3rd point. Got the response of ConnectionState but couldn't find a way in 'Go' to get the Server certificates and add them to tls.Config.

state := conn.ConnectionState()
for v := range state.PeerCertificates {
cert := &state.PeerCertificates[v]
}

transport := &http.Transport{
                        TLSClientConfig : tls.Config{Certificates: []tls.Certificate{}},}// get this cert

You need to set the RootCAs field of the tls.Config type.
This field contains the certificate authorities used to verify server certificates.

Create a x509 CertPool by using x509.NewCertPool function, and add to it all the certificates from state.PeerCertificates, using the AddCert method.

Again, I have not tested it.

> [...]


Manlio

laxman.v...@gmail.com

unread,
Apr 11, 2016, 5:35:57 AM4/11/16
to golang-nuts, laxman.v...@gmail.com
After the handshake failure, return value of connectionstate doesnt gave me peerCertificates(its empty). (Not Sure, why?)
http://play.golang.org/p/ttVVtC6Hog

Here is the output I get when I run this on ubuntu linux.
Get https://go.com: x509: certificate is valid for disney.com, www.disney.com, las1.origin.matterhorn.disney.com, not go.com
Received new response  <nil>

Server should have ideally sent public key and a private key. At client, these certificates need to be sent to Server during "Get".
I am blank if adding the RootCAs will do that.

Let me know if you have issue in the logic.

Manlio Perillo

unread,
Apr 11, 2016, 6:41:53 AM4/11/16
to golang-nuts, laxman.v...@gmail.com
Il giorno lunedì 11 aprile 2016 11:35:57 UTC+2, laxman.v...@gmail.com ha scritto:
After the handshake failure, return value of connectionstate doesnt gave me peerCertificates(its empty). (Not Sure, why?)
http://play.golang.org/p/ttVVtC6Hog

Here is the output I get when I run this on ubuntu linux.
Get https://go.com: x509: certificate is valid for disney.com, www.disney.com, las1.origin.matterhorn.disney.com, not go.com
Received new response  <nil>

Server should have ideally sent public key and a private key. At client, these certificates need to be sent to Server during "Get".
I am blank if adding the RootCAs will do that.

Let me know if you have issue in the logic.

My suggestion assumed that the handshake failure is caused by self signed certificates.  In your case the problem is that the certificate has an invalid Common Name.
In this case the only solution, IMHO, is to set InsecureSkipVerify to true, if handshake fails for a domain.

This is probably what browsers do.


Manlio

laxman.v...@gmail.com

unread,
Apr 13, 2016, 2:30:39 AM4/13/16
to golang-nuts, laxman.v...@gmail.com
Ok.. There was a misunderstanding in my analysis. But now it is cleared.

As you mentioned, adding an exception in browser is nothing but setting InsecureSkipVerify to true. It makes the browser or GO client to ignore the certificate validation and proceed with http request.

I was in assumption that browser perform certificate verification even after adding exception. 

Anyways, got to know more about ssl connection and helped alot.

Thanks 
Reply all
Reply to author
Forward
0 new messages