Use static test data for testing delegated credentials

This removes dependency on NewDelegatedCredential from tris.
This commit is contained in:
Christopher Patton 2018-07-19 18:44:03 -07:00 committed by Kris Kwiatkowski
parent 22d6deb0e7
commit 1ea9624098

View File

@ -5,24 +5,15 @@
package tls package tls
import ( import (
"bytes"
"crypto" "crypto"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/x509" "crypto/x509"
"errors" "encoding/asn1"
"encoding/pem"
"fmt" "fmt"
"testing" "testing"
"time" "time"
) )
// dcWithPrivateKey stores a delegated credential and its corresponding private
// key.
type dcWithPrivateKey struct {
*DelegatedCredential
privateKey crypto.PrivateKey
}
// These test keys were generated with the following program, available in the // These test keys were generated with the following program, available in the
// crypto/tls directory: // crypto/tls directory:
// //
@ -68,34 +59,80 @@ zP3NGxnDVqlMX+HI1+IuFXgQTVWvBdxPkw==
-----END EC PRIVATE KEY----- -----END EC PRIVATE KEY-----
` `
// Invalid TLS versions used for testing purposes. var dcTestDCsPEM = `-----BEGIN DC TEST DATA-----
const ( MIIGQzCCAToTBXRsczEyAgIDAwICBAMEga0ACUp3AFswWTATBgcqhkjOPQIBBggq
versionInvalidDC uint16 = 0xff00 hkjOPQMBBwNCAAQ9z9RDrMvyRzPOkw9SK2S/O5DiwfRNjAwYcq7e/sKdN0ZcSP1K
versionMalformedDC12 uint16 = 0xff12 se/+ZDXfruwyviuq+h5oSzWPoejHHx7jnwBTBAMASDBGAiEAtYH/x0Ue2B2a34WG
versionMalformedDC13 uint16 = 0xff13 Oj9wVPJeyYBXxIbUrCdqfoQzq2oCIQCJYtwRE9UJvAQKve4ulJOr+zGjN8jG4tdg
) 9YSb/yOQgQR5MHcCAQEEIOBCmSaGwzZtXOJRCbA03GgxegoSV5GasVjJlttpUAPh
oAoGCCqGSM49AwEHoUQDQgAEPc/UQ6zL8kczzpMPUitkvzuQ4sH0TYwMGHKu3v7C
nTdGXEj9SrHv/mQ1367sMr4rqvoeaEs1j6Hoxx8e458AUzCCATgTBXRsczEzAgJ/
FwICBAMEgasACUp3AFswWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARcqxvo0JO1
yiXoBhV/T2hmkUhwMnP5XtTJCGGfI0ILShmTeuTcScmiTuzo3qA/HVmr2sdnfBvx
zhQOYXrsfTNxBAMARjBEAiB8xrQk3DRFkACXMLZTJ1jAml/2zj/Vqc4cav0xi9zk
dQIgDSrNtkK1akKGeNt7Iquv0lLZgyLp1i+rwQwOTdbw6ScEeTB3AgEBBCC7JqZM
yIFzXdTmuYIUqOGQ602V4VtQttg/Oh2NuSCteKAKBggqhkjOPQMBB6FEA0IABFyr
G+jQk7XKJegGFX9PaGaRSHAyc/le1MkIYZ8jQgtKGZN65NxJyaJO7OjeoD8dWava
x2d8G/HOFA5heux9M3EwggE9EwdpbnZhbGlkAgMA/wACAgQDBIGtAAlKdwBbMFkw
EwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEdlKK5Dv35nOxaTS0LGqBnQstHSqVFIoZ
FsHGdXuR2N4pAoMkUF0w94+BZ/KHm1Djv/ugELm0aMHp8SBbJV3JVQQDAEgwRgIh
AL/gfo5JGFV/pNZe4ktc2yO41a4ipFvb8WIv8qn29gjoAiEAw1DB1EelNEfjl+fp
CDMT+mdFKRDMnXTRrM2K8gI1QsEEeTB3AgEBBCCdu3sMkUAsbHAcYOZ9wJnQujWr
5UqPQotIys9hqJ3PTaAKBggqhkjOPQMBB6FEA0IABHZSiuQ79+ZzsWk0tCxqgZ0L
LR0qlRSKGRbBxnV7kdjeKQKDJFBdMPePgWfyh5tQ47/7oBC5tGjB6fEgWyVdyVUw
ggFAEwttYWxmb3JtZWQxMgICAwMCAgQDBIGtAAlKdwBbMFkwEwYHKoZIzj0CAQYI
KoZIzj0DAQcDQgAEn8Rr7eedTHuGJjv7mglv7nJrV7KMDE2A33v8EAMGU+AvRq2m
XNIoc+a6JxpYetjTnT3s8TW4qWXq9dJzw3VAVgQDAEgwRgIhAKEVbifQNllzjTwX
s5CUsN42Eo8R8WTiFNSbhJmqDKsCAiEA4cqhQA2Cop2WtuOAG3aMnO9MKAPxLeUc
fEmnM658P3kEeTB3AgEBBCAR4EtE/WbJIc6id2bLOR4xgis7mzOWJdiRAiGKNshB
iKAKBggqhkjOPQMBB6FEA0IABF/2VNK9W/QsMdiBn3qdG19trNMAFvVM0JbeBHin
gl/7WVXGBk0WzgvmA0qSH4Bc7d8z8n3JKdmByYPgpxTjbFUwggFAEwttYWxmb3Jt
ZWQxMwICAwQCAgQDBIGtAAlKdwBbMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE
FGWBYWhjdr9al2imEFlGx+r0tQdcEqL/Qtf7imo/z5fr2z+tG3TawC0QeHU6uyRX
8zPvZGJ/Xps5q3RBI0tVggQDAEgwRgIhAMv30xlPKpajZuahNRHx3AlGtM9mNt5K
WbWvhqDXhlVgAiEAxqI0K57Y9p9lLC8cSoy2arppjPMWKkVA4G2ck2n4NwUEeTB3
AgEBBCCaruxlln2bwAX0EGy4oge0EpSDObt8Z+pNqx1nxDYyYKAKBggqhkjOPQMB
B6FEA0IABBYfBBlgDC3TLkbJJTTJaZMXiXvDkUiWMeYFpcbAHdvMI8zoS6b++Zgc
HJbn52hmB027JEIMPWsxKxPkr7udk7Q=
-----END DC TEST DATA-----
`
var dcTestConfig *Config type dcTestDC struct {
var dcTestCerts map[string]*Certificate Name string
var dcTestDCs map[uint16]dcWithPrivateKey Version int
var dcNow time.Time Scheme int
var dcTestDCScheme = ECDSAWithP521AndSHA512 DC []byte
var dcTestDCVersions = []uint16{ PrivateKey []byte
VersionTLS12,
VersionTLS13,
VersionTLS13Draft23,
versionInvalidDC,
} }
var dcTestDCs []dcTestDC
var dcTestConfig *Config
var dcTestDelegationCert Certificate
var dcTestCert Certificate
var dcTestNow time.Time
func init() { func init() {
// Use a static time for testing at whcih time the test certificates are // Parse the PEM-encoded DER block containing the test DCs.
// valid. block, _ := pem.Decode([]byte(dcTestDCsPEM))
dcNow = time.Date(2018, 07, 03, 18, 0, 0, 234234, time.UTC) if block == nil {
panic("failed to decode DC tests PEM block")
}
// Parse the DER-encoded test DCs.
_, err := asn1.Unmarshal(block.Bytes, &dcTestDCs)
if err != nil {
panic("failed to unmarshal DC test ASN.1 data")
}
// Use a static time for testing. This is the point at which the test DCs
// were generated.
dcTestNow = time.Date(2018, 07, 03, 18, 0, 0, 234234, time.UTC)
// The base configuration for the client and server.
dcTestConfig = &Config{ dcTestConfig = &Config{
Time: func() time.Time { Time: func() time.Time {
return dcNow return dcTestNow
}, },
Rand: zeroSource{}, Rand: zeroSource{},
Certificates: nil, Certificates: nil,
@ -104,230 +141,51 @@ func init() {
CipherSuites: allCipherSuites(), CipherSuites: allCipherSuites(),
} }
// The certificates of the server.
dcTestCerts = make(map[string]*Certificate)
var err error
// The delegation certificate. // The delegation certificate.
dcCert := new(Certificate) dcTestDelegationCert, err = X509KeyPair([]byte(delegatorCertPEM), []byte(delegatorKeyPEM))
*dcCert, err = X509KeyPair([]byte(delegatorCertPEM), []byte(delegatorKeyPEM))
if err != nil { if err != nil {
panic(err) panic(err)
} }
dcCert.Leaf, err = x509.ParseCertificate(dcCert.Certificate[0]) dcTestDelegationCert.Leaf, err = x509.ParseCertificate(dcTestDelegationCert.Certificate[0])
if err != nil { if err != nil {
panic(err) panic(err)
} }
dcTestCerts["dc"] = dcCert
// The standard certificate. // A certificate without the the DelegationUsage extension for X.509.
ndcCert := new(Certificate) dcTestCert, err = X509KeyPair([]byte(nonDelegatorCertPEM), []byte(nonDelegatorKeyPEM))
*ndcCert, err = X509KeyPair([]byte(nonDelegatorCertPEM), []byte(nonDelegatorKeyPEM))
if err != nil { if err != nil {
panic(err) panic(err)
} }
ndcCert.Leaf, err = x509.ParseCertificate(ndcCert.Certificate[0]) dcTestCert.Leaf, err = x509.ParseCertificate(dcTestCert.Certificate[0])
if err != nil { if err != nil {
panic(err) panic(err)
} }
dcTestCerts["no dc"] = ndcCert
// The root certificates for the client. // Make these roots of these certificates the client's trusted CAs.
dcTestConfig.RootCAs = x509.NewCertPool() dcTestConfig.RootCAs = x509.NewCertPool()
dcRoot, err := x509.ParseCertificate(dcCert.Certificate[len(dcCert.Certificate)-1]) raw := dcTestDelegationCert.Certificate[len(dcTestDelegationCert.Certificate)-1]
root, err := x509.ParseCertificate(raw)
if err != nil { if err != nil {
panic(err) panic(err)
} }
dcTestConfig.RootCAs.AddCert(dcRoot) dcTestConfig.RootCAs.AddCert(root)
ndcRoot, err := x509.ParseCertificate(ndcCert.Certificate[len(ndcCert.Certificate)-1]) raw = dcTestCert.Certificate[len(dcTestCert.Certificate)-1]
root, err = x509.ParseCertificate(raw)
if err != nil { if err != nil {
panic(err) panic(err)
} }
dcTestConfig.RootCAs.AddCert(ndcRoot) dcTestConfig.RootCAs.AddCert(root)
// A pool of DCs.
dcTestDCs = make(map[uint16]dcWithPrivateKey)
for _, vers := range dcTestDCVersions {
dc, sk, err := NewDelegatedCredential(dcCert, dcTestDCScheme, dcNow.Sub(dcCert.Leaf.NotBefore)+dcMaxTTL, vers)
if err != nil {
panic(err)
}
dcTestDCs[vers] = dcWithPrivateKey{dc, sk}
}
// Add two DCs with invalid private keys, one for TLS 1.2 and another for
// 1.3.
malformedDC12 := new(DelegatedCredential)
*malformedDC12 = *dcTestDCs[VersionTLS12].DelegatedCredential
dcTestDCs[versionMalformedDC12] = dcWithPrivateKey{
malformedDC12,
dcTestDCs[versionInvalidDC].privateKey,
}
malformedDC13 := new(DelegatedCredential)
*malformedDC13 = *dcTestDCs[VersionTLS13].DelegatedCredential
dcTestDCs[versionMalformedDC13] = dcWithPrivateKey{
malformedDC13,
dcTestDCs[versionInvalidDC].privateKey,
}
}
func checkECDSAPublicKeysEqual(
publicKey, publicKey2 crypto.PublicKey, scheme SignatureScheme) error {
curve := getCurve(scheme)
pk := publicKey.(*ecdsa.PublicKey)
pk2 := publicKey2.(*ecdsa.PublicKey)
serializedPublicKey := elliptic.Marshal(curve, pk.X, pk.Y)
serializedPublicKey2 := elliptic.Marshal(curve, pk2.X, pk2.Y)
if !bytes.Equal(serializedPublicKey2, serializedPublicKey) {
return errors.New("PublicKey mismatch")
}
return nil
}
// Test that cred and cred2 are equal.
func checkCredentialsEqual(dc, dc2 *DelegatedCredential) error {
if dc2.ValidTime != dc.ValidTime {
return fmt.Errorf("ValidTime mismatch: got %d; want %d", dc2.ValidTime, dc.ValidTime)
}
if dc2.publicKeyScheme != dc.publicKeyScheme {
return fmt.Errorf("scheme mismatch: got %04x; want %04x", dc2.publicKeyScheme, dc.publicKeyScheme)
}
return checkECDSAPublicKeysEqual(dc.PublicKey, dc2.PublicKey, dc.publicKeyScheme)
}
// Test delegation and validation of credentials.
func TestDelegateValidate(t *testing.T) {
ver := uint16(VersionTLS12)
cert := dcTestCerts["dc"]
validTime := dcNow.Sub(cert.Leaf.NotBefore) + dcMaxTTL
shortValidTime := dcNow.Sub(cert.Leaf.NotBefore) + time.Second
delegatedCred, _, err := NewDelegatedCredential(cert, ECDSAWithP256AndSHA256, validTime, ver)
if err != nil {
t.Fatal(err)
}
// Test validation of good DC.
if v, err := delegatedCred.Validate(cert.Leaf, ver, dcNow); err != nil {
t.Error(err)
} else if !v {
t.Error("good DC is invalid; want valid")
}
// Test validation of expired DC.
tooLate := dcNow.Add(dcMaxTTL).Add(time.Nanosecond)
if v, err := delegatedCred.Validate(cert.Leaf, ver, tooLate); err == nil {
t.Error("expired DC validation succeeded; want failure")
} else if v {
t.Error("expired DC is valid; want invalid")
}
// Test protocol binding.
if v, err := delegatedCred.Validate(cert.Leaf, VersionSSL30, dcNow); err != nil {
t.Fatal(err)
} else if v {
t.Error("DC with wrong version is valid; want invalid")
}
// Test signature algorithm binding.
delegatedCred.Scheme = ECDSAWithP521AndSHA512
if v, err := delegatedCred.Validate(cert.Leaf, ver, dcNow); err != nil {
t.Fatal(err)
} else if v {
t.Error("DC with wrong scheme is valid; want invalid")
}
delegatedCred.Scheme = ECDSAWithP256AndSHA256
// Test delegation cedrtificate binding.
cert.Leaf.Raw[0] ^= byte(42)
if v, err := delegatedCred.Validate(cert.Leaf, ver, dcNow); err != nil {
t.Fatal(err)
} else if v {
t.Error("DC with wrong cert is valid; want invalid")
}
cert.Leaf.Raw[0] ^= byte(42)
// Test validation of DC who's TTL is too long.
delegatedCred2, _, err := NewDelegatedCredential(cert, ECDSAWithP256AndSHA256, validTime+time.Second, ver)
if err != nil {
t.Fatal(err)
}
if v, err := delegatedCred2.Validate(cert.Leaf, ver, dcNow); err == nil {
t.Error("DC validation with long TTL succeeded; want failure")
} else if v {
t.Error("DC with long TTL is valid; want invalid")
}
// Test validation of DC who's TTL is short.
delegatedCred3, _, err := NewDelegatedCredential(cert, ECDSAWithP256AndSHA256, shortValidTime, ver)
if err != nil {
t.Fatal(err)
}
if v, err := delegatedCred3.Validate(cert.Leaf, ver, dcNow); err != nil {
t.Error(err)
} else if !v {
t.Error("good DC is invalid; want valid")
}
// Test validation of DC using a certificate that can't delegate.
if v, err := delegatedCred.Validate(
dcTestCerts["no dc"].Leaf, ver, dcNow); err != errNoDelegationUsage {
t.Error("DC validation with non-delegation cert succeeded; want failure")
} else if v {
t.Error("DC with non-delegation cert is valid; want invalid")
}
}
// Test encoding/decoding of delegated credentials.
func TestDelegatedCredentialMarshalUnmarshal(t *testing.T) {
cert := dcTestCerts["dc"]
delegatedCred, _, err := NewDelegatedCredential(cert,
ECDSAWithP256AndSHA256,
dcNow.Sub(cert.Leaf.NotBefore)+dcMaxTTL,
VersionTLS12)
if err != nil {
t.Fatal(err)
}
serialized, err := delegatedCred.Marshal()
if err != nil {
t.Error(err)
}
delegatedCred2, err := UnmarshalDelegatedCredential(serialized)
if err != nil {
t.Error(err)
}
err = checkCredentialsEqual(delegatedCred, delegatedCred2)
if err != nil {
t.Error(err)
}
if delegatedCred.Scheme != delegatedCred2.Scheme {
t.Errorf("scheme mismatch: got %04x; want %04x",
delegatedCred2.Scheme, delegatedCred.Scheme)
}
if !bytes.Equal(delegatedCred2.Signature, delegatedCred.Signature) {
t.Error("Signature mismatch")
}
} }
// Tests the handshake and one round of application data. Returns true if the // Tests the handshake and one round of application data. Returns true if the
// connection used a DC. // connection used a DC.
func testConnWithDC(t *testing.T, func testConnWithDC(t *testing.T, clientMsg, serverMsg string, clientConfig, serverConfig *Config) (bool, error) {
clientMsg, serverMsg string,
clientConfig, serverConfig *Config) (bool, error) {
ln := newLocalListener(t) ln := newLocalListener(t)
defer ln.Close() defer ln.Close()
// Listen for and serve a single client connection.
srvCh := make(chan *Conn, 1) srvCh := make(chan *Conn, 1)
var serr error var serr error
go func() { go func() {
@ -346,6 +204,7 @@ func testConnWithDC(t *testing.T,
srvCh <- srv srvCh <- srv
}() }()
// Dial the server.
cli, err := Dial("tcp", ln.Addr().String(), clientConfig) cli, err := Dial("tcp", ln.Addr().String(), clientConfig)
if err != nil { if err != nil {
return false, err return false, err
@ -363,12 +222,14 @@ func testConnWithDC(t *testing.T,
} }
buf := make([]byte, bufLen) buf := make([]byte, bufLen)
// Client sends a message to the server, which is read by the server.
cli.Write([]byte(clientMsg)) cli.Write([]byte(clientMsg))
n, err := srv.Read(buf) n, err := srv.Read(buf)
if n != len(clientMsg) || string(buf[:n]) != clientMsg { if n != len(clientMsg) || string(buf[:n]) != clientMsg {
return false, fmt.Errorf("Server read = %d, buf= %q; want %d, %s", n, buf, len(clientMsg), clientMsg) return false, fmt.Errorf("Server read = %d, buf= %q; want %d, %s", n, buf, len(clientMsg), clientMsg)
} }
// Server reads a message from the client, which is read by the client.
srv.Write([]byte(serverMsg)) srv.Write([]byte(serverMsg))
n, err = cli.Read(buf) n, err = cli.Read(buf)
if n != len(serverMsg) || err != nil || string(buf[:n]) != serverMsg { if n != len(serverMsg) || err != nil || string(buf[:n]) != serverMsg {
@ -389,76 +250,39 @@ func testServerGetCertificate(ch *ClientHelloInfo) (*Certificate, error) {
} }
if versOk && ch.AcceptsDelegatedCredential { if versOk && ch.AcceptsDelegatedCredential {
return dcTestCerts["dc"], nil return &dcTestDelegationCert, nil
} }
return dcTestCerts["no dc"], nil return &dcTestCert, nil
}
// Checks that the ciient supports the signature algorithm supported by the test
// server, and that the server has a DC for the selected protocol version.
func testServerGetDC(ch *ClientHelloInfo, vers uint16) (*DelegatedCredential, crypto.PrivateKey, error) {
schemeOk := false
for _, scheme := range ch.SignatureSchemes {
schemeOk = schemeOk || (scheme == dcTestDCScheme)
}
versOk := false
for _, testVers := range dcTestDCVersions {
versOk = versOk || (vers == testVers)
}
if schemeOk && versOk && ch.AcceptsDelegatedCredential {
d := dcTestDCs[vers]
return d.DelegatedCredential, d.privateKey, nil
}
return nil, nil, nil
}
// Returns a DC signed with a bad version number.
func testServerGetInvalidDC(ch *ClientHelloInfo, vers uint16) (*DelegatedCredential, crypto.PrivateKey, error) {
d := dcTestDCs[versionInvalidDC]
return d.DelegatedCredential, d.privateKey, nil
}
// Returns a DC with the wrong private key.
func testServerGetMalformedDC(ch *ClientHelloInfo, vers uint16) (*DelegatedCredential, crypto.PrivateKey, error) {
if vers == VersionTLS12 {
d := dcTestDCs[versionMalformedDC12]
return d.DelegatedCredential, d.privateKey, nil
} else if vers == VersionTLS13 {
d := dcTestDCs[versionMalformedDC13]
return d.DelegatedCredential, d.privateKey, nil
} else {
return nil, nil, fmt.Errorf("testServerGetMalformedDC: unsupported version %x", vers)
}
} }
// Various test cases for handshakes involving DCs.
var dcTests = []struct { var dcTests = []struct {
clientDC bool clientDC bool
serverDC bool serverDC bool
clientSkipVerify bool clientSkipVerify bool
clientMaxVers uint16 clientMaxVers uint16
serverMaxVers uint16 serverMaxVers uint16
useMalformedDC bool nowOffset time.Duration
useInvalidDC bool dcTestName string
expectSuccess bool expectSuccess bool
expectDC bool expectDC bool
name string name string
}{ }{
{true, true, false, VersionTLS12, VersionTLS12, false, false, true, true, "tls12"}, {true, true, false, VersionTLS12, VersionTLS12, 0, "tls12", true, true, "tls12"},
{true, true, false, VersionTLS13, VersionTLS13, false, false, true, true, "tls13"}, {true, true, false, VersionTLS13, VersionTLS13, 0, "tls13", true, true, "tls13"},
{true, true, false, VersionTLS12, VersionTLS12, true, false, false, false, "tls12, malformed dc"}, {true, true, false, VersionTLS12, VersionTLS12, 0, "malformed12", false, false, "tls12, malformed dc"},
{true, true, false, VersionTLS13, VersionTLS13, true, false, false, false, "tls13, malformed dc"}, {true, true, false, VersionTLS13, VersionTLS13, 0, "malformed13", false, false, "tls13, malformed dc"},
{true, true, true, VersionTLS12, VersionTLS12, false, true, true, true, "tls12, invalid dc, skip verify"}, {true, true, true, VersionTLS12, VersionTLS12, 0, "invalid", true, true, "tls12, invalid dc, skip verify"},
{true, true, true, VersionTLS13, VersionTLS13, false, true, true, true, "tls13, invalid dc, skip verify"}, {true, true, true, VersionTLS13, VersionTLS13, 0, "invalid", true, true, "tls13, invalid dc, skip verify"},
{false, true, false, VersionTLS12, VersionTLS12, false, false, true, false, "client no dc"}, {false, true, false, VersionTLS12, VersionTLS12, 0, "tls12", true, false, "client no dc"},
{true, false, false, VersionTLS12, VersionTLS12, false, false, true, false, "server no dc"}, {true, false, false, VersionTLS12, VersionTLS12, 0, "tls12", true, false, "server no dc"},
{true, true, false, VersionTLS11, VersionTLS12, false, false, true, false, "client old"}, {true, true, false, VersionTLS11, VersionTLS12, 0, "tls12", true, false, "client old"},
{true, true, false, VersionTLS12, VersionTLS11, false, false, true, false, "server old"}, {true, true, false, VersionTLS12, VersionTLS11, 0, "tls12", true, false, "server old"},
{true, true, false, VersionTLS13, VersionTLS13, dcMaxTTL, "tls13", false, false, "expired dc"},
} }
// Tests the handshake with the delegated credential extension. // Tests the handshake with the delegated credential extension for each test
// case in dcTests.
func TestDCHandshake(t *testing.T) { func TestDCHandshake(t *testing.T) {
serverMsg := "hello" serverMsg := "hello"
clientMsg := "world" clientMsg := "world"
@ -468,24 +292,36 @@ func TestDCHandshake(t *testing.T) {
serverConfig.GetCertificate = testServerGetCertificate serverConfig.GetCertificate = testServerGetCertificate
for i, test := range dcTests { for i, test := range dcTests {
clientConfig.AcceptDelegatedCredential = test.clientDC clientConfig.MaxVersion = test.clientMaxVers
serverConfig.MaxVersion = test.serverMaxVers
clientConfig.InsecureSkipVerify = test.clientSkipVerify clientConfig.InsecureSkipVerify = test.clientSkipVerify
clientConfig.AcceptDelegatedCredential = test.clientDC
clientConfig.Time = func() time.Time {
return dcTestNow.Add(time.Duration(test.nowOffset))
}
if test.serverDC { if test.serverDC {
if test.useInvalidDC { serverConfig.GetDelegatedCredential = func(
serverConfig.GetDelegatedCredential = testServerGetInvalidDC ch *ClientHelloInfo, vers uint16) (*DelegatedCredential, crypto.PrivateKey, error) {
} else if test.useMalformedDC { for _, t := range dcTestDCs {
serverConfig.GetDelegatedCredential = testServerGetMalformedDC if t.Name == test.dcTestName {
} else { dc, err := UnmarshalDelegatedCredential(t.DC)
serverConfig.GetDelegatedCredential = testServerGetDC if err != nil {
return nil, nil, err
}
sk, err := x509.ParseECPrivateKey(t.PrivateKey)
if err != nil {
return nil, nil, err
}
return dc, sk, nil
}
}
return nil, nil, fmt.Errorf("Test DC with name '%s' not found", test.dcTestName)
} }
} else { } else {
serverConfig.GetDelegatedCredential = nil serverConfig.GetDelegatedCredential = nil
} }
clientConfig.MaxVersion = test.clientMaxVers
serverConfig.MaxVersion = test.serverMaxVers
usedDC, err := testConnWithDC(t, clientMsg, serverMsg, clientConfig, serverConfig) usedDC, err := testConnWithDC(t, clientMsg, serverMsg, clientConfig, serverConfig)
if err != nil && test.expectSuccess { if err != nil && test.expectSuccess {
t.Errorf("test #%d (%s) fails: %s", i+1, test.name, err) t.Errorf("test #%d (%s) fails: %s", i+1, test.name, err)