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

advancedtls: Add SNI logic to ServerOptions.GetCertificate #3697

Merged
merged 30 commits into from Jul 28, 2020
Merged
Changes from 7 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
0650ecb
Add GetCertificateWithSNI func
Jun 16, 2020
c358cff
Add comments in GetCertificateWithSNI
Jun 16, 2020
1f0088b
Modify comments in GetCertificateWithSNI
Jun 16, 2020
edada75
Restructure SNI
Jun 18, 2020
cda3e2d
Modified comments
Jun 18, 2020
40eadfc
Fixed arguments name
Jun 18, 2020
9e74bb7
Review Comments #1
Jun 18, 2020
4adb63c
Review comments #2
Jun 18, 2020
62c0f22
Made tests compiled after changing the func signature
Jun 20, 2020
d2343cc
Cleaned up comments
Jun 21, 2020
292f227
Fixed advancedtls unit test
Jun 22, 2020
9e81777
Fixed unit test and integration test for advancedtls
cindyxue Jun 22, 2020
7eeb1d6
Clean up comments
Jun 22, 2020
b76410b
Clean up comments
Jun 22, 2020
3519dc6
Added unit test for getCertificateWithSNI
Jun 30, 2020
d2cc061
Added unit test for getCertificateWithSNI
cindyxue Jun 30, 2020
c811fa5
Merge branch 'master' into Cindy/SNI
cindyxue Jun 30, 2020
df72ccd
Separate out buildGetCertificateFunc for go1.9
Jul 6, 2020
b066d6a
Review comments #3
Jul 10, 2020
ec327de
Review comments #4
Jul 16, 2020
cc37b1d
Regenerated certificate and added a test case to test DNS field for SNI
Jul 16, 2020
3891625
Removed const var in function
Jul 22, 2020
ec83efb
Renamed GetCertificate and buildGetCertificateFunc
Jul 24, 2020
789296a
Resolved Easwars' comments
Jul 24, 2020
8ef1de7
Added server_cert_3.txt
Jul 24, 2020
c70c90b
Renamed serverPeerCert to serverCert
Jul 24, 2020
fea90e1
Added server_cert_1.txt and server_cert_2.txt
Jul 24, 2020
783ab29
Separated unit test for go1.10+ and go1.9
Jul 24, 2020
18570bb
Changed comparing method to cmp.Equal
Jul 25, 2020
d1206c6
Resolved minor issues
Jul 28, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
32 changes: 30 additions & 2 deletions security/advancedtls/advancedtls.go
Expand Up @@ -164,7 +164,7 @@ type ServerOptions struct {
// invoke this function every time asked to present certificates to the
// client when a new connection is established. This is known as peer
// certificate reloading.
GetCertificate func(*tls.ClientHelloInfo) (*tls.Certificate, error)
GetCertificate func(*tls.ClientHelloInfo) (*[]tls.Certificate, error)
cindyxue marked this conversation as resolved.
Show resolved Hide resolved
// VerifyPeer is a custom verification check after certificate signature
// check.
// If this is set, we will perform this customized check after doing the
Expand Down Expand Up @@ -211,10 +211,13 @@ func (o *ServerOptions) config() (*tls.Config, error) {
// buildVerifyFunc.
clientAuth = tls.RequireAnyClientCert
}
getCertificateWithSNI := func(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error) {
return o.getCertificateWithSNI(clientHello)
}
config := &tls.Config{
ClientAuth: clientAuth,
Certificates: o.Certificates,
GetCertificate: o.GetCertificate,
GetCertificate: getCertificateWithSNI,
}
if o.RootCACerts != nil {
config.ClientCAs = o.RootCACerts
Expand Down Expand Up @@ -475,3 +478,28 @@ func cloneTLSConfig(cfg *tls.Config) *tls.Config {
}
return cfg.Clone()
}

// GetCertificateWithSNI is a helper function that returns the certificate
// that matches the SNI field based on the given ClientHelloInfo
// if GetCertificate returns a list of certificates
func (o *ServerOptions) getCertificateWithSNI(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error) {
cindyxue marked this conversation as resolved.
Show resolved Hide resolved
certificates, err := o.GetCertificate(clientHello)
if err != nil {
return nil, err
}
if len(*certificates) == 0 {
cindyxue marked this conversation as resolved.
Show resolved Hide resolved
return nil, fmt.Errorf("No certificates configured")
}
// If users pass in only one certificate, return that certificate
if len(*certificates) == 1 {
return &(*certificates)[0], nil
}
// Choose the SNI certificate using SupportsCertificate
for _, cert := range *certificates {
if err := clientHello.SupportsCertificate(&cert); err == nil {
return &cert, nil
}
}
// If nothing matches, return the first certificate.
return &(*certificates)[0], nil
}