Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

crypto/tls: feature request: add option to JUST skip hostname verification #21971

Closed
rsm10 opened this issue Sep 21, 2017 · 14 comments
Closed

crypto/tls: feature request: add option to JUST skip hostname verification #21971

rsm10 opened this issue Sep 21, 2017 · 14 comments
Labels
Milestone

Comments

@rsm10
Copy link

@rsm10 rsm10 commented Sep 21, 2017

I understand in "fca335e" we made changes to enforce either requiring ServerName or InsecureSkipVerify to be set in our tls libraries.

What about making this the default behaviour but having a "SkipHostnameVerification" option? I have a situation where we are using certs signed by our own private CA. The hostname verification won't work since we pre-generate certs using a CN that isn't an actual DSN/Host name. I still want to validate that other servers certs are at least signed by the same private CA as the client but JUST want to skip the hostnameVerify check. Today that doesn't seem possible.

@ianlancetaylor ianlancetaylor changed the title feature request: add option to JUST skip hostname verification crypto/tls: feature request: add option to JUST skip hostname verification Sep 21, 2017
@ianlancetaylor ianlancetaylor added this to the Unplanned milestone Sep 21, 2017
@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Sep 21, 2017

@FiloSottile

This comment has been minimized.

Copy link
Member

@FiloSottile FiloSottile commented Sep 28, 2017

You can currently do this by using VerifyPeerCertificate and (*Certificate).Verify (and remembering to put the remaining rawCerts into VerifyOptions.Intermediates).

certs := make([]*x509.Certificate, len(certMsg.certificates))
for i, asn1Data := range certMsg.certificates {
cert, err := x509.ParseCertificate(asn1Data)
if err != nil {
c.sendAlert(alertBadCertificate)
return errors.New("tls: failed to parse certificate from server: " + err.Error())
}
certs[i] = cert
}
if !c.config.InsecureSkipVerify {
opts := x509.VerifyOptions{
Roots: c.config.RootCAs,
CurrentTime: c.config.time(),
DNSName: c.config.ServerName,
Intermediates: x509.NewCertPool(),
}
for i, cert := range certs {
if i == 0 {
continue
}
opts.Intermediates.AddCert(cert)
}
c.verifiedChains, err = certs[0].Verify(opts)
if err != nil {
c.sendAlert(alertBadCertificate)
return err
}
}

I don't think this is common enough to add another verification option to the already crowded tls.Config.

@rsm10

This comment has been minimized.

Copy link
Author

@rsm10 rsm10 commented Oct 5, 2017

@rsm10

This comment has been minimized.

Copy link
Author

@rsm10 rsm10 commented Oct 17, 2017

As to your original suggestion, curious why on lines 334-336 we seem to skip the first cert in the chain?

	if i == 0 { 
		continue 
	}
@FiloSottile

This comment has been minimized.

Copy link
Member

@FiloSottile FiloSottile commented Oct 17, 2017

The first cert is the leaf, and it’s used on line 339. All the others are intermediates and are used on line 337.

@rsc

This comment has been minimized.

Copy link
Contributor

@rsc rsc commented Oct 23, 2017

Problem is I want to use a library (rafthttp) that only exposes a transport.TLSInfo (https://github.com/coreos/etcd/blob/master/pkg/transport/listener.go) , not a tls Config

This is a very special case. I would suggest working with the library maintainers (or just having your own fork) to expose the tls.Config. We shouldn't add a second way to do something in the standard library (especially a somewhat confusing security knob) just because one downstream package hides the first way.

@benma

This comment has been minimized.

Copy link

@benma benma commented Aug 14, 2018

I am also interested in skipping the hostname verification only. The problem is that if the ServerName is unset, it ill be inferred. As stated above, one way to achieve it is to set InsecureSkipVerify to true and copy/paste the code from the stdlib to config.VerifyPeerCertificate, but that is suboptimal, as one would miss fixes done to this part of the code in the stdlib.

👍 for a SkipHostnameVerification option.

@sikemullivan

This comment has been minimized.

Copy link

@sikemullivan sikemullivan commented Nov 23, 2018

👍 for a SkipHostnameVerification option as well.

Trying to get client authentication working with MySQL. Using a self-signed cert because I'm running everything out of VPS machines. Everything is IP based. Has anyone built the code for the suggested work around? I don't want to reinvent the wheel.

@sikemullivan

This comment has been minimized.

Copy link

@sikemullivan sikemullivan commented Nov 23, 2018

Awesome, thanks for the quick response.

@sikemullivan

This comment has been minimized.

Copy link

@sikemullivan sikemullivan commented Nov 23, 2018

@benma

Should line 109 set the verified chains? Or does it not matter?

Now:

_, err := certs[0].Verify(opts)
return err

Then:

verifiedChains, err := certs[0].Verify(opts)
return err
@benma

This comment has been minimized.

Copy link

@benma benma commented Nov 23, 2018

Based on a quick look through the stdlib, I would say it would make sense, yes. Seems to be exposed only in conn.ConnectionState(), and conn.VerifyHostname(). Not sure why I didn't put it in back then.

That was too quick. I looked again, and verifiedChains is input to the function, not output. The api/callback doesn't support setting verifiedChains (which should probably be fixed upstream).

@sikemullivan

This comment has been minimized.

Copy link

@sikemullivan sikemullivan commented Nov 23, 2018

Agree, everything seems to work without it getting returned. Thanks for your help.

@gopherbot

This comment has been minimized.

Copy link

@gopherbot gopherbot commented Sep 5, 2019

Change https://golang.org/cl/193620 mentions this issue: crypto/tls: add ExampleConfig_VerifyPeerCertificate

gopherbot pushed a commit that referenced this issue Nov 9, 2019
Setting InsecureSkipVerify and VerifyPeerCertificate is the recommended
way to customize and override certificate validation.

However, there is boilerplate involved and it usually requires first
reimplementing the default validation strategy to then customize it.
Provide an example that does the same thing as the default as a starting
point.

Examples of where we directed users to do something similar are in
issues #35467, #31791, #28754, #21971, and #24151.

Fixes #31792

Change-Id: Id033e9fa3cac9dff1f7be05c72dfb34b4f973fd4
Reviewed-on: https://go-review.googlesource.com/c/go/+/193620
Reviewed-by: Adam Langley <agl@golang.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
7 participants
You can’t perform that action at this time.