From 0d6e4561a665eaa4b4dfd4d94093e4b0b4354aac Mon Sep 17 00:00:00 2001 From: Christopher Patton Date: Thu, 9 Aug 2018 11:47:38 -0700 Subject: [PATCH] Add DC test data for tls13draft28 and tls13rfc (#117) The test in subcerts_test.go only passes if maxVersion == VersionTLS13Draft23. This is because DCs are cryptographically bound to the protocol version on the wire. To work around this as we move towards the RFC, this PR adds test data for VersionTLS13Draft28 and VersionTLS13 and uses maxVersion to pick which data to load. # Please enter the commit message for your changes. Lines starting --- subcerts_test.go | 171 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 160 insertions(+), 11 deletions(-) diff --git a/subcerts_test.go b/subcerts_test.go index 5b96484..0c86fed 100644 --- a/subcerts_test.go +++ b/subcerts_test.go @@ -9,6 +9,7 @@ import ( "crypto/x509" "encoding/asn1" "encoding/pem" + "errors" "fmt" "testing" "time" @@ -68,9 +69,13 @@ type dcTestDC struct { PrivateKey []byte } -// Test data used for testing the TLS handshake with the delegated creedential -// extension. The PEM block encodes a DER encoded slice of dcTestDC's. -var dcTestDCsPEM = `-----BEGIN DC TEST DATA----- +// Test data used for testing the TLS handshake with the delegated credential +// extension. The PEM block encodes a DER encoded slice of dcTestDCs. + +// Use with maxVersion == VersionTLS13Draft23. +// +// TODO(henrydcase): Remove this when we drop support for draft23. +var dcTestDataDraft23PEM = `-----BEGIN DC TEST DATA----- MIIIPDCCAUETCXRsczEzcDI1NgICfxcCAgQDBIGwAAk6gAQDfxcAWzBZMBMGByqG SM49AgEGCCqGSM49AwEHA0IABDFeK+EcMQWKDM6xZJqHEHLcIWE0iHTAL1xAB5r6 bkm7GLlz1HLWcTy28PNsb9KQLV3Yeay2WYA2d2zGQjNbEhcEAwBHMEUCIQDnXyP4 @@ -118,6 +123,145 @@ AiEiKCRicw1Upfdy+xdSF0N3XXkLHB13criCfJr2rbZ1o8V7CsX6U70o+/48huPI -----END DC TEST DATA----- ` +// Use with maxVersion == VersionTLS13Draft28. +// +// TODO(henrydcase): Remove this when we drop support for draft28. +var dcTestDataDraft28PEM = `-----BEGIN DC TEST DATA----- +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 +-----END DC TEST DATA----- +` + +// Use with maxVersion == VersionTLS13. +var dcTestDataPEM = `-----BEGIN DC TEST DATA----- +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 +-----END DC TEST DATA-----` + +// Parses the input PEM block containing the test DCs. +func dcLoadTestData(in []byte, out *[]dcTestDC) error { + block, _ := pem.Decode(in) + if block == nil { + return errors.New("failed to decode DC tests PEM block") + } + + // Parse the DER-encoded test DCs. + _, err := asn1.Unmarshal(block.Bytes, out) + if err != nil { + return errors.New("failed to unmarshal DC test ASN.1 data") + } + + // Check that the test data is for the right version. This should be + // maxVersion, defined in common.go. + for _, test := range *out { + dc, err := unmarshalDelegatedCredential(test.DC) + if err != nil { + return err + } + + // Sanity check that test version matches the version encoded by the DC. + testVersion := uint16(test.Version) + if dc.cred.expectedVersion != testVersion { + return fmt.Errorf( + "test version doesn't match credential version: got: 0x0%04x; want: 0x%04x", + testVersion, dc.cred.expectedVersion) + } + + // With the exception of "badvers" and "tsl12", all test DCs should have + // the expected verison. + if test.Name != "badvers" && test.Name != "tls12" && testVersion != maxVersion { + return fmt.Errorf( + "encountered test with wrong version: got: 0x0%04x; want: 0x%04x", + test.Version, maxVersion) + } + } + return nil +} + var dcTestDCs []dcTestDC var dcTestConfig *Config var dcTestDelegationCert Certificate @@ -125,16 +269,21 @@ var dcTestCert Certificate var dcTestNow time.Time func init() { - // Parse the PEM block containing the test DCs. - block, _ := pem.Decode([]byte(dcTestDCsPEM)) - if block == nil { - panic("failed to decode DC tests PEM block") + // Load the DC test data. + var testData []byte + switch maxVersion { + case VersionTLS13Draft23: + testData = []byte(dcTestDataDraft23PEM) + case 0x7f00 | 28: // TODO(henrydcase): Fix once draft 28 is implemented + testData = []byte(dcTestDataDraft28PEM) + case 0x0304: // TODO(henrydcase): Fix once the final version is implemented + testData = []byte(dcTestDataPEM) + default: + panic(fmt.Errorf("no test data for version %04x", maxVersion)) } - - // Parse the DER-encoded test DCs. - _, err := asn1.Unmarshal(block.Bytes, &dcTestDCs) + err := dcLoadTestData(testData, &dcTestDCs) if err != nil { - panic("failed to unmarshal DC test ASN.1 data") + panic(err) } // The base configuration for the client and server.