-
Notifications
You must be signed in to change notification settings - Fork 160
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fully implement retransmition flow specified in RFC6347 Section 4.2.4. - parse incoming handshake message sequentially instead of calling type switch for each message - fix condition to end client handshake - return read error transparently from underlying connection - support packet contains both handshake and encrypted message (OpenSSL send such packet.) - verify CipherSuite on changeCipherSpec and flight cache epoch number
- Loading branch information
Showing
28 changed files
with
2,417 additions
and
1,705 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package dtls | ||
|
||
import ( | ||
"crypto/tls" | ||
"reflect" | ||
"testing" | ||
|
||
"github.com/pion/dtls/v2/pkg/crypto/selfsign" | ||
) | ||
|
||
func TestGetCertificate(t *testing.T) { | ||
certificateWildcard, err := selfsign.GenerateSelfSignedWithDNS("*.test.test") | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
certificateTest, err := selfsign.GenerateSelfSignedWithDNS("test.test", "www.test.test", "pop.test.test") | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
certificateRandom, err := selfsign.GenerateSelfSigned() | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
cfg := &handshakeConfig{ | ||
localCertificates: []tls.Certificate{ | ||
certificateRandom, | ||
certificateTest, | ||
certificateWildcard, | ||
}, | ||
} | ||
|
||
testCases := []struct { | ||
desc string | ||
serverName string | ||
expectedCertificate tls.Certificate | ||
}{ | ||
{ | ||
desc: "Simple match in CN", | ||
serverName: "test.test", | ||
expectedCertificate: certificateTest, | ||
}, | ||
{ | ||
desc: "Simple match in SANs", | ||
serverName: "www.test.test", | ||
expectedCertificate: certificateTest, | ||
}, | ||
|
||
{ | ||
desc: "Wildcard match", | ||
serverName: "foo.test.test", | ||
expectedCertificate: certificateWildcard, | ||
}, | ||
{ | ||
desc: "No match return first", | ||
serverName: "foo.bar", | ||
expectedCertificate: certificateRandom, | ||
}, | ||
} | ||
|
||
for _, test := range testCases { | ||
test := test | ||
|
||
t.Run(test.desc, func(t *testing.T) { | ||
t.Parallel() | ||
|
||
cert, err := cfg.getCertificate(test.serverName) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
if !reflect.DeepEqual(cert.Leaf, test.expectedCertificate.Leaf) { | ||
t.Fatalf("Certificate does not match: expected(%v) actual(%v)", test.expectedCertificate.Leaf, cert.Leaf) | ||
} | ||
}) | ||
} | ||
} |
Oops, something went wrong.