Skip to content

Commit

Permalink
Add option to allow non-standard Common Name (CN) in SSL certificate …
Browse files Browse the repository at this point in the history
…verification. (#705)

msdsn: add option to allow non-standard Common Name (CN) in SSL certificate verification
  • Loading branch information
jsimonweb authored Dec 11, 2021
1 parent 191d776 commit 324eb10
Showing 1 changed file with 41 additions and 16 deletions.
57 changes: 41 additions & 16 deletions msdsn/conn_str.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,27 +75,52 @@ type Config struct {
}

func SetupTLS(certificate string, insecureSkipVerify bool, hostInCertificate string) (*tls.Config, error) {
var config tls.Config
if certificate != "" {
pem, err := ioutil.ReadFile(certificate)
if err != nil {
return nil, fmt.Errorf("cannot read certificate %q: %v", certificate, err)
config := tls.Config{
ServerName: hostInCertificate,

// fix for https://github.com/denisenkom/go-mssqldb/issues/166
// Go implementation of TLS payload size heuristic algorithm splits single TDS package to multiple TCP segments,
// while SQL Server seems to expect one TCP segment per encrypted TDS package.
// Setting DynamicRecordSizingDisabled to true disables that algorithm and uses 16384 bytes per TLS package
DynamicRecordSizingDisabled: true,
}
if len(certificate) == 0 {
return &config, nil
}
pem, err := ioutil.ReadFile(certificate)
if err != nil {
return nil, fmt.Errorf("cannot read certificate %q: %v", certificate, err)
}
if strings.Contains(config.ServerName, ":") && !insecureSkipVerify {
// fix for https://github.com/denisenkom/go-mssqldb/issues/704
// A SSL/TLS certificate Common Name (CN) containing the ":" character
// (which is a non-standard character) will cause normal verification to fail.
// Since the VerifyConnection callback runs after normal certificate
// verification, confirm that SetupTLS() has been called
// with "insecureSkipVerify=false", then InsecureSkipVerify must be set to true
// for this VerifyConnection callback to accomplish certificate verification.
config.InsecureSkipVerify = true
config.VerifyConnection = func(cs tls.ConnectionState) error {
commonName := cs.PeerCertificates[0].Subject.CommonName
if commonName != cs.ServerName {
return fmt.Errorf("invalid certificate name %q, expected %q", commonName, cs.ServerName)
}
opts := x509.VerifyOptions{
Roots: nil,
Intermediates: x509.NewCertPool(),
}
opts.Intermediates.AppendCertsFromPEM(pem)
_, err := cs.PeerCertificates[0].Verify(opts)
return err
}
certs := x509.NewCertPool()
certs.AppendCertsFromPEM(pem)
config.RootCAs = certs
return &config, nil
}
certs := x509.NewCertPool()
certs.AppendCertsFromPEM(pem)
config.RootCAs = certs
if insecureSkipVerify {
config.InsecureSkipVerify = true
}
config.ServerName = hostInCertificate

// fix for https://github.com/denisenkom/go-mssqldb/issues/166
// Go implementation of TLS payload size heuristic algorithm splits single TDS package to multiple TCP segments,
// while SQL Server seems to expect one TCP segment per encrypted TDS package.
// Setting DynamicRecordSizingDisabled to true disables that algorithm and uses 16384 bytes per TLS package
config.DynamicRecordSizingDisabled = true

return &config, nil
}

Expand Down

0 comments on commit 324eb10

Please sign in to comment.