diff options
Diffstat (limited to 'vendor/github.com/pion/dtls/v2/certificate.go')
-rw-r--r-- | vendor/github.com/pion/dtls/v2/certificate.go | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/vendor/github.com/pion/dtls/v2/certificate.go b/vendor/github.com/pion/dtls/v2/certificate.go new file mode 100644 index 0000000..c99e1c9 --- /dev/null +++ b/vendor/github.com/pion/dtls/v2/certificate.go @@ -0,0 +1,67 @@ +package dtls + +import ( + "crypto/tls" + "crypto/x509" + "strings" +) + +func (c *handshakeConfig) getCertificate(serverName string) (*tls.Certificate, error) { + c.mu.Lock() + defer c.mu.Unlock() + + if c.nameToCertificate == nil { + nameToCertificate := make(map[string]*tls.Certificate) + for i := range c.localCertificates { + cert := &c.localCertificates[i] + x509Cert := cert.Leaf + if x509Cert == nil { + var parseErr error + x509Cert, parseErr = x509.ParseCertificate(cert.Certificate[0]) + if parseErr != nil { + continue + } + } + if len(x509Cert.Subject.CommonName) > 0 { + nameToCertificate[strings.ToLower(x509Cert.Subject.CommonName)] = cert + } + for _, san := range x509Cert.DNSNames { + nameToCertificate[strings.ToLower(san)] = cert + } + } + c.nameToCertificate = nameToCertificate + } + + if len(c.localCertificates) == 0 { + return nil, errNoCertificates + } + + if len(c.localCertificates) == 1 { + // There's only one choice, so no point doing any work. + return &c.localCertificates[0], nil + } + + if len(serverName) == 0 { + return &c.localCertificates[0], nil + } + + name := strings.TrimRight(strings.ToLower(serverName), ".") + + if cert, ok := c.nameToCertificate[name]; ok { + return cert, nil + } + + // try replacing labels in the name with wildcards until we get a + // match. + labels := strings.Split(name, ".") + for i := range labels { + labels[i] = "*" + candidate := strings.Join(labels, ".") + if cert, ok := c.nameToCertificate[candidate]; ok { + return cert, nil + } + } + + // If nothing matches, return the first certificate. + return &c.localCertificates[0], nil +} |