diff --git a/ssl/ssl_cert.cc b/ssl/ssl_cert.cc index cd09d847bc..932b4801cb 100644 --- a/ssl/ssl_cert.cc +++ b/ssl/ssl_cert.cc @@ -859,6 +859,16 @@ UniquePtr DC::Parse(CRYPTO_BUFFER *in, uint8_t *out_alert) { return nullptr; } + // RFC 9345 forbids algorithms that use the rsaEncryption OID. As the + // RSASSA-PSS OID is unusably complicated, this effectively means we will not + // support RSA delegated credentials. + if (SSL_get_signature_algorithm_key_type(dc->dc_cert_verify_algorithm) == + EVP_PKEY_RSA) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SIGNATURE_ALGORITHM); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return nullptr; + } + return dc; } diff --git a/ssl/test/runner/cert.pem b/ssl/test/runner/cert.pem deleted file mode 100644 index c360dc7317..0000000000 --- a/ssl/test/runner/cert.pem +++ /dev/null @@ -1,22 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDtTCCAp2gAwIBAgIJALW2IrlaBKUhMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX -aWRnaXRzIFB0eSBMdGQwHhcNMTYwNzA5MDQzODA5WhcNMTYwODA4MDQzODA5WjBF -MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50 -ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB -CgKCAQEAugvahBkSAUF1fC49vb1bvlPrcl80kop1iLpiuYoz4Qptwy57+EWssZBc -HprZ5BkWf6PeGZ7F5AX1PyJbGHZLqvMCvViP6pd4MFox/igESISEHEixoiXCzepB -rhtp5UQSjHD4D4hKtgdMgVxX+LRtwgW3mnu/vBu7rzpr/DS8io99p3lqZ1Aky+aN -lcMj6MYy8U+YFEevb/V0lRY9oqwmW7BHnXikm/vi6sjIS350U8zb/mRzYeIs2R65 -LUduTL50+UMgat9ocewI2dv8aO9Dph+8NdGtg8LFYyTTHcUxJoMr1PTOgnmET19W -JH4PrFwk7ZE1QJQQ1L4iKmPeQistuQIDAQABo4GnMIGkMB0GA1UdDgQWBBT5m6Vv -zYjVYHG30iBE+j2XDhUE8jB1BgNVHSMEbjBsgBT5m6VvzYjVYHG30iBE+j2XDhUE -8qFJpEcwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNV -BAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZIIJALW2IrlaBKUhMAwGA1UdEwQF -MAMBAf8wDQYJKoZIhvcNAQELBQADggEBAD7Jg68SArYWlcoHfZAB90Pmyrt5H6D8 -LRi+W2Ri1fBNxREELnezWJ2scjl4UMcsKYp4Pi950gVN+62IgrImcCNvtb5I1Cfy -/MNNur9ffas6X334D0hYVIQTePyFk3umI+2mJQrtZZyMPIKSY/sYGQHhGGX6wGK+ -GO/og0PQk/Vu6D+GU2XRnDV0YZg1lsAsHd21XryK6fDmNkEMwbIWrts4xc7scRrG -HWy+iMf6/7p/Ak/SIicM4XSwmlQ8pPxAZPr+E2LoVd9pMpWUwpW2UbtO5wsGTrY5 -sO45tFNN/y+jtUheB1C2ijObG/tXELaiyCdM+S/waeuv0MXtI4xnn1A= ------END CERTIFICATE----- diff --git a/ssl/test/runner/channel_id_key.pem b/ssl/test/runner/channel_id_key.pem index 604752bcda..83eb53a459 100644 --- a/ssl/test/runner/channel_id_key.pem +++ b/ssl/test/runner/channel_id_key.pem @@ -1,5 +1,5 @@ ------BEGIN EC PRIVATE KEY----- -MHcCAQEEIPwxu50c7LEhVNRYJFRWBUnoaz7JSos96T5hBp4rjyptoAoGCCqGSM49 -AwEHoUQDQgAEzFSVTE5guxJRQ0VbZ8dicPs5e/DT7xpW7Yc9hq0VOchv7cbXuI/T -CwadDjGWX/oaz0ftFqrVmfkwZu+C58ioWg== ------END EC PRIVATE KEY----- +-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg/DG7nRzssSFU1Fgk +VFYFSehrPslKiz3pPmEGniuPKm2hRANCAATMVJVMTmC7ElFDRVtnx2Jw+zl78NPv +Glbthz2GrRU5yG/txte4j9MLBp0OMZZf+hrPR+0WqtWZ+TBm74LnyKha +-----END PRIVATE KEY----- diff --git a/ssl/test/runner/cipher_suites.go b/ssl/test/runner/cipher_suites.go index 5db57498be..8bbde8e6e4 100644 --- a/ssl/test/runner/cipher_suites.go +++ b/ssl/test/runner/cipher_suites.go @@ -28,8 +28,8 @@ type keyAgreement interface { // In the case that the key agreement protocol doesn't use a // ServerKeyExchange message, generateServerKeyExchange can return nil, // nil. - generateServerKeyExchange(*Config, *Certificate, *clientHelloMsg, *serverHelloMsg, uint16) (*serverKeyExchangeMsg, error) - processClientKeyExchange(*Config, *Certificate, *clientKeyExchangeMsg, uint16) ([]byte, error) + generateServerKeyExchange(*Config, *CertificateChain, *clientHelloMsg, *serverHelloMsg, uint16) (*serverKeyExchangeMsg, error) + processClientKeyExchange(*Config, *CertificateChain, *clientKeyExchangeMsg, uint16) ([]byte, error) // On the client side, the next two methods are called in order. diff --git a/ssl/test/runner/common.go b/ssl/test/runner/common.go index 024c921095..cd10e14641 100644 --- a/ssl/test/runner/common.go +++ b/ssl/test/runner/common.go @@ -10,9 +10,12 @@ import ( "crypto/ecdsa" "crypto/rand" "crypto/x509" + "crypto/x509/pkix" + "encoding/pem" "fmt" "io" "math/big" + "os" "strings" "sync" "time" @@ -434,18 +437,18 @@ type Config struct { // If Time is nil, TLS uses time.Now. Time func() time.Time - // Certificates contains one or more certificate chains + // Chains contains one or more certificate chains // to present to the other side of the connection. // Server configurations must include at least one certificate. - Certificates []Certificate + Chains []CertificateChain - // NameToCertificate maps from a certificate name to an element of - // Certificates. Note that a certificate name can be of the form + // NameToChain maps from a certificate name to an element of + // Chains. Note that a certificate name can be of the form // '*.example.com' and so doesn't have to be a domain name as such. // See Config.BuildNameToCertificate - // The nil value causes the first element of Certificates to be used + // The nil value causes the first element of Chains to be used // for all connections. - NameToCertificate map[string]*Certificate + NameToChain map[string]*CertificateChain // RootCAs defines the set of root certificate authorities // that clients use when verifying server certificates. @@ -1842,7 +1845,7 @@ type ProtocolBugs struct { // RenegotiationCertificate, if not nil, is the certificate to use on // renegotiation handshakes. - RenegotiationCertificate *Certificate + RenegotiationCertificate *CertificateChain // ExpectNoCertificateAuthoritiesExtension, if true, causes the client to // reject CertificateRequest with the CertificateAuthorities extension. @@ -2126,12 +2129,12 @@ func (c *Config) supportedVersions(isDTLS, requireTLS13 bool) []uint16 { } // getCertificateForName returns the best certificate for the given name, -// defaulting to the first element of c.Certificates if there are no good +// defaulting to the first element of c.Chains if there are no good // options. -func (c *Config) getCertificateForName(name string) *Certificate { - if len(c.Certificates) == 1 || c.NameToCertificate == nil { +func (c *Config) getCertificateForName(name string) *CertificateChain { + if len(c.Chains) == 1 || c.NameToChain == nil { // There's only one choice, so no point doing any work. - return &c.Certificates[0] + return &c.Chains[0] } name = strings.ToLower(name) @@ -2139,7 +2142,7 @@ func (c *Config) getCertificateForName(name string) *Certificate { name = name[:len(name)-1] } - if cert, ok := c.NameToCertificate[name]; ok { + if cert, ok := c.NameToChain[name]; ok { return cert } @@ -2149,13 +2152,13 @@ func (c *Config) getCertificateForName(name string) *Certificate { for i := range labels { labels[i] = "*" candidate := strings.Join(labels, ".") - if cert, ok := c.NameToCertificate[candidate]; ok { + if cert, ok := c.NameToChain[candidate]; ok { return cert } } // If nothing matches, return the first certificate. - return &c.Certificates[0] + return &c.Chains[0] } func (c *Config) signSignatureAlgorithms() []signatureAlgorithm { @@ -2172,28 +2175,28 @@ func (c *Config) verifySignatureAlgorithms() []signatureAlgorithm { return supportedSignatureAlgorithms } -// BuildNameToCertificate parses c.Certificates and builds c.NameToCertificate +// BuildNameToCertificate parses c.Chains and builds c.NameToCertificate // from the CommonName and SubjectAlternateName fields of each of the leaf // certificates. func (c *Config) BuildNameToCertificate() { - c.NameToCertificate = make(map[string]*Certificate) - for i := range c.Certificates { - cert := &c.Certificates[i] + c.NameToChain = make(map[string]*CertificateChain) + for i := range c.Chains { + cert := &c.Chains[i] x509Cert, err := x509.ParseCertificate(cert.Certificate[0]) if err != nil { continue } if len(x509Cert.Subject.CommonName) > 0 { - c.NameToCertificate[x509Cert.Subject.CommonName] = cert + c.NameToChain[x509Cert.Subject.CommonName] = cert } for _, san := range x509Cert.DNSNames { - c.NameToCertificate[san] = cert + c.NameToChain[san] = cert } } } -// A Certificate is a chain of one or more certificates, leaf first. -type Certificate struct { +// A CertificateChain is a chain of one or more certificates, leaf first. +type CertificateChain struct { Certificate [][]byte PrivateKey crypto.PrivateKey // supported types: *rsa.PrivateKey, *ecdsa.PrivateKey // OCSPStaple contains an optional OCSP response which will be served @@ -2208,6 +2211,15 @@ type Certificate struct { // processing for TLS clients doing client authentication. If nil, the // leaf certificate will be parsed as needed. Leaf *x509.Certificate + // ChainPath is the path to the temporary on disk copy of the certificate + // chain. + ChainPath string + // KeyPath is the path to the temporary on disk copy of the key. + KeyPath string + // RootPath is the path to the temporary on disk copy of the root of the + // certificate chain. If the chain only contains one certificate ChainPath + // and RootPath will be the same. + RootPath string } // A TLS record. @@ -2419,3 +2431,90 @@ func isAllZero(v []byte) bool { } return true } + +var baseCertTemplate = &x509.Certificate{ + SerialNumber: big.NewInt(57005), + Subject: pkix.Name{ + CommonName: "test cert", + Country: []string{"US"}, + Province: []string{"Some-State"}, + Organization: []string{"Internet Widgits Pty Ltd"}, + }, + NotBefore: time.Now().Add(-time.Hour), + NotAfter: time.Now().Add(time.Hour), + DNSNames: []string{"test"}, + IsCA: true, + BasicConstraintsValid: true, +} + +var tmpDir string + +func generateSingleCertChain(template *x509.Certificate, key crypto.Signer, ocspStaple, sctList []byte) CertificateChain { + cert := generateTestCert(template, nil, key, ocspStaple, sctList) + tmpCertPath, tmpKeyPath := writeTempCertFile([]*x509.Certificate{cert}), writeTempKeyFile(key) + return CertificateChain{ + Certificate: [][]byte{cert.Raw}, + PrivateKey: key, + OCSPStaple: ocspStaple, + SignedCertificateTimestampList: sctList, + Leaf: cert, + ChainPath: tmpCertPath, + KeyPath: tmpKeyPath, + RootPath: tmpCertPath, + } +} + +func writeTempCertFile(certs []*x509.Certificate) string { + f, err := os.CreateTemp(tmpDir, "test-cert") + if err != nil { + panic(fmt.Sprintf("failed to create temp file: %s", err)) + } + for _, cert := range certs { + if _, err := f.Write(pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: cert.Raw})); err != nil { + panic(fmt.Sprintf("failed to write test certificate: %s", err)) + } + } + tmpCertPath := f.Name() + if err := f.Close(); err != nil { + panic(fmt.Sprintf("failed to close test certificate temp file: %s", err)) + } + return tmpCertPath +} + +func writeTempKeyFile(privKey crypto.Signer) string { + f, err := os.CreateTemp(tmpDir, "test-key") + if err != nil { + panic(fmt.Sprintf("failed to create temp file: %s", err)) + } + keyDER, err := x509.MarshalPKCS8PrivateKey(privKey) + if err != nil { + panic(fmt.Sprintf("failed to marshal test key: %s", err)) + } + if _, err := f.Write(pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: keyDER})); err != nil { + panic(fmt.Sprintf("failed to write test key: %s", err)) + } + tmpKeyPath := f.Name() + if err := f.Close(); err != nil { + panic(fmt.Sprintf("failed to close test key temp file: %s", err)) + } + return tmpKeyPath +} + +func generateTestCert(template, issuer *x509.Certificate, key crypto.Signer, ocspStaple, sctList []byte) *x509.Certificate { + if template == nil { + template = baseCertTemplate + } + if issuer == nil { + issuer = template + } + der, err := x509.CreateCertificate(rand.Reader, template, issuer, key.Public(), key) + if err != nil { + panic(fmt.Sprintf("failed to create test certificate: %s", err)) + } + cert, err := x509.ParseCertificate(der) + if err != nil { + panic(fmt.Sprintf("failed to parse test certificate: %s", err)) + } + + return cert +} diff --git a/ssl/test/runner/ecdsa_p224_cert.pem b/ssl/test/runner/ecdsa_p224_cert.pem deleted file mode 100644 index 29246a2eac..0000000000 --- a/ssl/test/runner/ecdsa_p224_cert.pem +++ /dev/null @@ -1,12 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIBvjCCAWygAwIBAgIJAPlkrPTq4HgnMAoGCCqGSM49BAMCMEUxCzAJBgNVBAYT -AkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRn -aXRzIFB0eSBMdGQwHhcNMTcwMjI3MjAxOTIzWhcNMTkwMjI3MjAxOTIzWjBFMQsw -CQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJu -ZXQgV2lkZ2l0cyBQdHkgTHRkME4wEAYHKoZIzj0CAQYFK4EEACEDOgAE6dul6dL0 -+CyooFiKK4V+EYNYPbMZoLTxRcjRgrw3db6QzBAviDSxKADTVuyRmaVC74Mf6boB -HDmjUDBOMB0GA1UdDgQWBBSMtlkUJ7SCZ4zRqkjXMWvOebSgpTAfBgNVHSMEGDAW -gBSMtlkUJ7SCZ4zRqkjXMWvOebSgpTAMBgNVHRMEBTADAQH/MAoGCCqGSM49BAMC -A0AAMD0CHHolWPktSLbVMy9ukQUb2E7+Jb3hcNFqAXh47pYCHQC+jv2EE6oOEZ9F -tLkFLtap71+83P0NUEJX4Etu ------END CERTIFICATE----- diff --git a/ssl/test/runner/ecdsa_p256_cert.pem b/ssl/test/runner/ecdsa_p256_cert.pem deleted file mode 100644 index 50bcbf5bfd..0000000000 --- a/ssl/test/runner/ecdsa_p256_cert.pem +++ /dev/null @@ -1,12 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC -QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp -dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ -BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l -dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni -v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa -HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw -HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ -BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E -BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ= ------END CERTIFICATE----- diff --git a/ssl/test/runner/ecdsa_p384_cert.pem b/ssl/test/runner/ecdsa_p384_cert.pem deleted file mode 100644 index 1fd3fec63d..0000000000 --- a/ssl/test/runner/ecdsa_p384_cert.pem +++ /dev/null @@ -1,15 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICZTCCAeugAwIBAgIJAN+/LubpDwxNMAkGByqGSM49BAEwRTELMAkGA1UEBhMC -QVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdp -dHMgUHR5IEx0ZDAeFw0xNjA3MDkwMDAxMzJaFw0xNjA4MDgwMDAxMzJaMEUxCzAJ -BgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5l -dCBXaWRnaXRzIFB0eSBMdGQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQOdTJNqxiZ -+B68tCZV4GEJwDJ18jK9gFzvefcEAQluBijjrMjflL+RZAT64ExWzedRMp9PD9CW -Tz9hG/Kz4q/l952YsIhy7LTGXzwy7549WUOi+N3aW8psDjtwzWNZXqWjgacwgaQw -HQYDVR0OBBYEFKmYPjADcOlogOMU6D9wlftIWMj6MHUGA1UdIwRuMGyAFKmYPjAD -cOlogOMU6D9wlftIWMj6oUmkRzBFMQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29t -ZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkggkA378u -5ukPDE0wDAYDVR0TBAUwAwEB/zAJBgcqhkjOPQQBA2kAMGYCMQDTfL0OkRGnS5Ze -tsxagAuZqM2Zyv5a2g7u6eFLCx2rpTuQndWOtEnmVo3wjTDtkDcCMQCg+05XSqEF -cqxdXMZJMhqj2jS+tWucdgDstp/1KzJkbsupSjBzIycjVBKLdRwtNg8= ------END CERTIFICATE----- diff --git a/ssl/test/runner/ecdsa_p521_cert.pem b/ssl/test/runner/ecdsa_p521_cert.pem deleted file mode 100644 index 8b9a1e8384..0000000000 --- a/ssl/test/runner/ecdsa_p521_cert.pem +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICrzCCAhGgAwIBAgIJAMZT7oSqTg/lMAkGByqGSM49BAEwRTELMAkGA1UEBhMC -QVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdp -dHMgUHR5IEx0ZDAeFw0xNjA3MDkwMDAwNTBaFw0xNjA4MDgwMDAwNTBaMEUxCzAJ -BgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5l -dCBXaWRnaXRzIFB0eSBMdGQwgZswEAYHKoZIzj0CAQYFK4EEACMDgYYABAFD0TiZ -InCoCYDI66FvoaZ0tniUhaNk2YnjEPikfmYHDwstbqkTEqnGAq3pKF2y/MHTBXFd -E0KcFOPs5Ju8EgIcqwGvCkwHPmZtvvOrf+nJNHdm1gZfBUy09f3fVe/mHwfM2++H -dz54nHKxtQqvdafhmMV77R/rBuI24MLKbMihxRgQKaOBpzCBpDAdBgNVHQ4EFgQU -mLWm6ZtGfvih6iFx0+duYfHjGsYwdQYDVR0jBG4wbIAUmLWm6ZtGfvih6iFx0+du -YfHjGsahSaRHMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEw -HwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGSCCQDGU+6Eqk4P5TAMBgNV -HRMEBTADAQH/MAkGByqGSM49BAEDgYwAMIGIAkIBL/oEXMMQH9fefVd8onvgQbWI -/CJXYE+kLO15gO8satasGutVpXtYGeP8gZeuHrq+jWxzj7dGM7YzkW0pAu+wOAkC -QgFJSvKFcmbreLIjuwYik5aXeaUnTCvTQumG07cF0hZRgCf/kTxxmu2ffRoGCDTz -XoPqlxwaO7K+gaAS//CvR0E3lw== ------END CERTIFICATE----- diff --git a/ssl/test/runner/ed25519_cert.pem b/ssl/test/runner/ed25519_cert.pem deleted file mode 100644 index 308c2c9d28..0000000000 --- a/ssl/test/runner/ed25519_cert.pem +++ /dev/null @@ -1,11 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIBkTCCAUOgAwIBAgIJAJwooam0UCDmMAUGAytlcDBFMQswCQYDVQQGEwJBVTET -MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ -dHkgTHRkMB4XDTE0MDQyMzIzMjE1N1oXDTE0MDUyMzIzMjE1N1owRTELMAkGA1UE -BhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdp -ZGdpdHMgUHR5IEx0ZDAqMAUGAytlcAMhANdamAGCsQq31Uv+08lkBzoO4XLz2qYj -Ja8CGmj3B1Eao1AwTjAdBgNVHQ4EFgQUoux7eV+fJK2v3ah6QPU/lj1/+7UwHwYD -VR0jBBgwFoAUoux7eV+fJK2v3ah6QPU/lj1/+7UwDAYDVR0TBAUwAwEB/zAFBgMr -ZXADQQBuCzqji8VP9xU8mHEMjXGChX7YP5J664UyVKHKH9Z1u4wEbB8dJ3ScaWSL -r+VHVKUhsrvcdCelnXRrrSD7xWAL ------END CERTIFICATE----- diff --git a/ssl/test/runner/handshake_client.go b/ssl/test/runner/handshake_client.go index cd23337e16..41840d7191 100644 --- a/ssl/test/runner/handshake_client.go +++ b/ssl/test/runner/handshake_client.go @@ -1183,7 +1183,7 @@ func (hs *clientHandshakeState) doTLS13Handshake(msg interface{}) error { return err } - var chainToSend *Certificate + var chainToSend *CertificateChain var certReq *certificateRequestMsg if c.didResume { // Copy over authentication from the session. @@ -1691,7 +1691,7 @@ func (hs *clientHandshakeState) doFullHandshake() error { } } - var chainToSend *Certificate + var chainToSend *CertificateChain var certRequested bool certReq, ok := msg.(*certificateRequestMsg) if ok { @@ -1769,7 +1769,7 @@ func (hs *clientHandshakeState) doFullHandshake() error { } // Determine the hash to sign. - privKey := c.config.Certificates[0].PrivateKey + privKey := c.config.Chains[0].PrivateKey if certVerify.hasSignatureAlgorithm { certVerify.signatureAlgorithm, err = selectSignatureAlgorithm(c.vers, privKey, c.config, certReq.signatureAlgorithms) @@ -2403,18 +2403,18 @@ func (hs *clientHandshakeState) writeServerHash(msg []byte) { // selectClientCertificate selects a certificate for use with the given // certificate, or none if none match. It may return a particular certificate or // nil on success, or an error on internal error. -func selectClientCertificate(c *Conn, certReq *certificateRequestMsg) (*Certificate, error) { - if len(c.config.Certificates) == 0 { +func selectClientCertificate(c *Conn, certReq *certificateRequestMsg) (*CertificateChain, error) { + if len(c.config.Chains) == 0 { return nil, nil } // The test is assumed to have configured the certificate it meant to // send. - if len(c.config.Certificates) > 1 { + if len(c.config.Chains) > 1 { return nil, errors.New("tls: multiple certificates configured") } - return &c.config.Certificates[0], nil + return &c.config.Chains[0], nil } // clientSessionCacheKey returns a key used to cache sessionTickets that could diff --git a/ssl/test/runner/handshake_server.go b/ssl/test/runner/handshake_server.go index 7c3b587ab3..3cae911706 100644 --- a/ssl/test/runner/handshake_server.go +++ b/ssl/test/runner/handshake_server.go @@ -36,7 +36,7 @@ type serverHandshakeState struct { finishedHash finishedHash masterSecret []byte certsFromClient [][]byte - cert *Certificate + cert *CertificateChain finishedBytes []byte echHPKEContext *hpke.Context echConfigID uint8 @@ -1579,11 +1579,11 @@ func (hs *serverHandshakeState) processClientExtensions(serverExtensions *server if len(hs.clientHello.serverName) > 0 { c.serverName = hs.clientHello.serverName } - if len(config.Certificates) == 0 { + if len(config.Chains) == 0 { c.sendAlert(alertInternalError) return errors.New("tls: no certificates configured") } - hs.cert = &config.Certificates[0] + hs.cert = &config.Chains[0] if len(hs.clientHello.serverName) > 0 { hs.cert = config.getCertificateForName(hs.clientHello.serverName) } diff --git a/ssl/test/runner/key_agreement.go b/ssl/test/runner/key_agreement.go index 1053e4f46e..94d2543057 100644 --- a/ssl/test/runner/key_agreement.go +++ b/ssl/test/runner/key_agreement.go @@ -38,7 +38,7 @@ type rsaKeyAgreement struct { exportKey *rsa.PrivateKey } -func (ka *rsaKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg, version uint16) (*serverKeyExchangeMsg, error) { +func (ka *rsaKeyAgreement) generateServerKeyExchange(config *Config, cert *CertificateChain, clientHello *clientHelloMsg, hello *serverHelloMsg, version uint16) (*serverKeyExchangeMsg, error) { // Save the client version for comparison later. ka.clientVersion = clientHello.vers @@ -95,7 +95,7 @@ func (ka *rsaKeyAgreement) generateServerKeyExchange(config *Config, cert *Certi return skx, nil } -func (ka *rsaKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) { +func (ka *rsaKeyAgreement) processClientKeyExchange(config *Config, cert *CertificateChain, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) { preMasterSecret := make([]byte, 48) _, err := io.ReadFull(config.rand(), preMasterSecret[2:]) if err != nil { @@ -362,7 +362,7 @@ func curveForCurveID(id CurveID, config *Config) (ecdhCurve, bool) { // keyAgreementAuthentication is a helper interface that specifies how // to authenticate the ServerKeyExchange parameters. type keyAgreementAuthentication interface { - signParameters(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg, params []byte) (*serverKeyExchangeMsg, error) + signParameters(config *Config, cert *CertificateChain, clientHello *clientHelloMsg, hello *serverHelloMsg, params []byte) (*serverKeyExchangeMsg, error) verifyParameters(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, key crypto.PublicKey, params []byte, sig []byte) error } @@ -370,7 +370,7 @@ type keyAgreementAuthentication interface { // agreement parameters. type nilKeyAgreementAuthentication struct{} -func (ka *nilKeyAgreementAuthentication) signParameters(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg, params []byte) (*serverKeyExchangeMsg, error) { +func (ka *nilKeyAgreementAuthentication) signParameters(config *Config, cert *CertificateChain, clientHello *clientHelloMsg, hello *serverHelloMsg, params []byte) (*serverKeyExchangeMsg, error) { skx := new(serverKeyExchangeMsg) skx.key = params return skx, nil @@ -388,7 +388,7 @@ type signedKeyAgreement struct { peerSignatureAlgorithm signatureAlgorithm } -func (ka *signedKeyAgreement) signParameters(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg, params []byte) (*serverKeyExchangeMsg, error) { +func (ka *signedKeyAgreement) signParameters(config *Config, cert *CertificateChain, clientHello *clientHelloMsg, hello *serverHelloMsg, params []byte) (*serverKeyExchangeMsg, error) { // The message to be signed is prepended by the randoms. var msg []byte msg = append(msg, clientHello.random...) @@ -494,7 +494,7 @@ type ecdheKeyAgreement struct { peerKey []byte } -func (ka *ecdheKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg, version uint16) (*serverKeyExchangeMsg, error) { +func (ka *ecdheKeyAgreement) generateServerKeyExchange(config *Config, cert *CertificateChain, clientHello *clientHelloMsg, hello *serverHelloMsg, version uint16) (*serverKeyExchangeMsg, error) { var curveid CurveID preferredCurves := config.curvePreferences() @@ -545,7 +545,7 @@ NextCandidate: return ka.auth.signParameters(config, cert, clientHello, hello, serverECDHParams) } -func (ka *ecdheKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) { +func (ka *ecdheKeyAgreement) processClientKeyExchange(config *Config, cert *CertificateChain, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) { if len(ckx.ciphertext) == 0 || int(ckx.ciphertext[0]) != len(ckx.ciphertext)-1 { return nil, errClientKeyExchange } @@ -612,11 +612,11 @@ func (ka *ecdheKeyAgreement) peerSignatureAlgorithm() signatureAlgorithm { // exchange. type nilKeyAgreement struct{} -func (ka *nilKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg, version uint16) (*serverKeyExchangeMsg, error) { +func (ka *nilKeyAgreement) generateServerKeyExchange(config *Config, cert *CertificateChain, clientHello *clientHelloMsg, hello *serverHelloMsg, version uint16) (*serverKeyExchangeMsg, error) { return nil, nil } -func (ka *nilKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) { +func (ka *nilKeyAgreement) processClientKeyExchange(config *Config, cert *CertificateChain, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) { if len(ckx.ciphertext) != 0 { return nil, errClientKeyExchange } @@ -664,7 +664,7 @@ type pskKeyAgreement struct { identityHint string } -func (ka *pskKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg, version uint16) (*serverKeyExchangeMsg, error) { +func (ka *pskKeyAgreement) generateServerKeyExchange(config *Config, cert *CertificateChain, clientHello *clientHelloMsg, hello *serverHelloMsg, version uint16) (*serverKeyExchangeMsg, error) { // Assemble the identity hint. bytes := make([]byte, 2+len(config.PreSharedKeyIdentity)) bytes[0] = byte(len(config.PreSharedKeyIdentity) >> 8) @@ -691,7 +691,7 @@ func (ka *pskKeyAgreement) generateServerKeyExchange(config *Config, cert *Certi return skx, nil } -func (ka *pskKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) { +func (ka *pskKeyAgreement) processClientKeyExchange(config *Config, cert *CertificateChain, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) { // First, process the PSK identity. if len(ckx.ciphertext) < 2 { return nil, errClientKeyExchange diff --git a/ssl/test/runner/rsa_1024_cert.pem b/ssl/test/runner/rsa_1024_cert.pem deleted file mode 100644 index 4de4f49a34..0000000000 --- a/ssl/test/runner/rsa_1024_cert.pem +++ /dev/null @@ -1,15 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX -aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF -MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50 -ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB -gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci -HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV -W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV -HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f -Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht -ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr -T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f -j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg== ------END CERTIFICATE----- diff --git a/ssl/test/runner/key.pem b/ssl/test/runner/rsa_2048_key.pem similarity index 100% rename from ssl/test/runner/key.pem rename to ssl/test/runner/rsa_2048_key.pem diff --git a/ssl/test/runner/rsa_chain_cert.pem b/ssl/test/runner/rsa_chain_cert.pem deleted file mode 100644 index 8eb6e60eda..0000000000 --- a/ssl/test/runner/rsa_chain_cert.pem +++ /dev/null @@ -1,35 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIC0jCCAbqgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEQiBD -QTAeFw0xNjAyMjgyMDI3MDNaFw0yNjAyMjUyMDI3MDNaMBgxFjAUBgNVBAMMDUNs -aWVudCBDZXJ0IEEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRvaz8 -CC/cshpCafJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/ -kLRcH89M/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3 -tHb+xs2PSs8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+c -IDs2rQ+lP7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1 -z7C8jU50Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9V -iLeXANgZi+Xx9KgfAgMBAAGjLzAtMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYI -KwYBBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQBFEVbmYl+2RtNw -rDftRDF1v2QUbcN2ouSnQDHxeDQdSgasLzT3ui8iYu0Rw2WWcZ0DV5e0ztGPhWq7 -AO0B120aFRMOY+4+bzu9Q2FFkQqc7/fKTvTDzIJI5wrMnFvUfzzvxh3OHWMYSs/w -giq33hTKeHEq6Jyk3btCny0Ycecyc3yGXH10sizUfiHlhviCkDuESk8mFDwDDzqW -ZF0IipzFbEDHoIxLlm3GQxpiLoEV4k8KYJp3R5KBLFyxM6UGPz8h72mIPCJp2RuK -MYgF91UDvVzvnYm6TfseM2+ewKirC00GOrZ7rEcFvtxnKSqYf4ckqfNdSU1Y+RRC -1ngWZ7Ih ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICwjCCAaqgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJQyBS -b290IENBMB4XDTE2MDIyODIwMjcwM1oXDTI2MDIyNTIwMjcwM1owDzENMAsGA1UE -AwwEQiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALsSCYmDip2D -GkjFxw7ykz26JSjELkl6ArlYjFJ3aT/SCh8qbS4gln7RH8CPBd78oFdfhIKQrwtZ -3/q21ykD9BAS3qHe2YdcJfm8/kWAy5DvXk6NXU4qX334KofBAEpgdA/igEFq1P1l -HAuIfZCpMRfT+i5WohVsGi8f/NgpRvVaMONLNfgw57mz1lbtFeBEISmX0kbsuJxF -Qj/Bwhi5/0HAEXG8e7zN4cEx0yPRvmOATRdVb/8dW2pwOHRJq9R5M0NUkIsTSnL7 -6N/z8hRAHMsV3IudC5Yd7GXW1AGu9a+iKU+Q4xcZCoj0DC99tL4VKujrV1kAeqsM -cz5/dKzi6+cCAwEAAaMjMCEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC -AQYwDQYJKoZIhvcNAQELBQADggEBAIIeZiEeNhWWQ8Y4D+AGDwqUUeG8NjCbKrXQ -BlHg5wZ8xftFaiP1Dp/UAezmx2LNazdmuwrYB8lm3FVTyaPDTKEGIPS4wJKHgqH1 -QPDhqNm85ey7TEtI9oYjsNim/Rb+iGkIAMXaxt58SzxbjvP0kMr1JfJIZbic9vye -NwIspMFIpP3FB8ywyu0T0hWtCQgL4J47nigCHpOu58deP88fS/Nyz/fyGVWOZ76b -WhWwgM3P3X95fQ3d7oFPR/bVh0YV+Cf861INwplokXgXQ3/TCQ+HNXeAMWn3JLWv -XFwk8owk9dq/kQGdndGgy3KTEW4ctPX5GNhf3LJ9Q7dLji4ReQ4= ------END CERTIFICATE----- diff --git a/ssl/test/runner/rsa_chain_key.pem b/ssl/test/runner/rsa_chain_key.pem deleted file mode 100644 index d94d704422..0000000000 --- a/ssl/test/runner/rsa_chain_key.pem +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDRvaz8CC/cshpC -afJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/kLRcH89M -/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3tHb+xs2P -Ss8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+cIDs2rQ+l -P7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1z7C8jU50 -Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9ViLeXANgZ -i+Xx9KgfAgMBAAECggEBAK0VjSJzkyPaamcyTVSWjo7GdaBGcK60lk657RjR+lK0 -YJ7pkej4oM2hdsVZFsP8Cs4E33nXLa/0pDsRov/qrp0WQm2skwqGMC1I/bZ0WRPk -wHaDrBBfESWnJDX/AGpVtlyOjPmgmK6J2usMPihQUDkKdAYrVWJePrMIxt1q6BMe -iczs3qriMmtY3bUc4UyUwJ5fhDLjshHvfuIpYQyI6EXZM6dZksn9LylXJnigY6QJ -HxOYO0BDwOsZ8yQ8J8afLk88i0GizEkgE1z3REtQUwgWfxr1WV/ud+T6/ZhSAgH9 -042mQvSFZnIUSEsmCvjhWuAunfxHKCTcAoYISWfzWpkCgYEA7gpf3HHU5Tn+CgUn -1X5uGpG3DmcMgfeGgs2r2f/IIg/5Ac1dfYILiybL1tN9zbyLCJfcbFpWBc9hJL6f -CPc5hUiwWFJqBJewxQkC1Ae/HakHbip+IZ+Jr0842O4BAArvixk4Lb7/N2Ct9sTE -NJO6RtK9lbEZ5uK61DglHy8CS2UCgYEA4ZC1o36kPAMQBggajgnucb2yuUEelk0f -AEr+GI32MGE+93xMr7rAhBoqLg4AITyIfEnOSQ5HwagnIHonBbv1LV/Gf9ursx8Z -YOGbvT8zzzC+SU1bkDzdjAYnFQVGIjMtKOBJ3K07++ypwX1fr4QsQ8uKL8WSOWwt -Z3Bym6XiZzMCgYADnhy+2OwHX85AkLt+PyGlPbmuelpyTzS4IDAQbBa6jcuW/2wA -UE2km75VUXmD+u2R/9zVuLm99NzhFhSMqlUxdV1YukfqMfP5yp1EY6m/5aW7QuIP -2MDa7TVL9rIFMiVZ09RKvbBbQxjhuzPQKL6X/PPspnhiTefQ+dl2k9xREQKBgHDS -fMfGNEeAEKezrfSVqxphE9/tXms3L+ZpnCaT+yu/uEr5dTIAawKoQ6i9f/sf1/Sy -xedsqR+IB+oKrzIDDWMgoJybN4pkZ8E5lzhVQIjFjKgFdWLzzqyW9z1gYfABQPlN -FiS20WX0vgP1vcKAjdNrHzc9zyHBpgQzDmAj3NZZAoGBAI8vKCKdH7w3aL5CNkZQ -2buIeWNA2HZazVwAGG5F2TU/LmXfRKnG6dX5bkU+AkBZh56jNZy//hfFSewJB4Kk -buB7ERSdaNbO21zXt9FEA3+z0RfMd/Zv2vlIWOSB5nzl/7UKti3sribK6s9ZVLfi -SxpiPQ8d/hmSGwn4ksrWUsJD ------END PRIVATE KEY----- diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go index 22674bd67c..9d53ab6fbc 100644 --- a/ssl/test/runner/runner.go +++ b/ssl/test/runner/runner.go @@ -18,11 +18,13 @@ import ( "bytes" "crypto" "crypto/ecdsa" + "crypto/ed25519" "crypto/elliptic" "crypto/rand" "crypto/rsa" "crypto/x509" "crypto/x509/pkix" + _ "embed" "encoding/base64" "encoding/binary" "encoding/hex" @@ -36,7 +38,6 @@ import ( "net" "os" "os/exec" - "path" "path/filepath" "runtime" "strconv" @@ -69,7 +70,6 @@ var ( shimPath = flag.String("shim-path", "../../../build/ssl/test/bssl_shim", "The location of the shim binary.") shimExtraFlags = flag.String("shim-extra-flags", "", "Semicolon-separated extra flags to pass to the shim binary on each invocation.") handshakerPath = flag.String("handshaker-path", "../../../build/ssl/test/handshaker", "The location of the handshaker binary.") - resourceDir = flag.String("resource-dir", ".", "The directory in which to find certificate and key files.") fuzzer = flag.Bool("fuzzer", false, "If true, tests against a BoringSSL built in fuzzer mode.") transcriptDir = flag.String("transcript-dir", "", "The directory in which to write transcripts.") idleTimeout = flag.Duration("idle-timeout", 15*time.Second, "The number of seconds to wait for a read or write to bssl_shim.") @@ -117,110 +117,93 @@ var shimConfig ShimConfiguration = ShimConfiguration{ HalfRTTTickets: 2, } -type testCert int +//go:embed rsa_2048_key.pem +var rsa2048KeyPEM []byte -const ( - testCertRSA testCert = iota - testCertRSA1024 - testCertRSAChain - testCertECDSAP224 - testCertECDSAP256 - testCertECDSAP384 - testCertECDSAP521 - testCertEd25519 -) +//go:embed rsa_1024_key.pem +var rsa1024KeyPEM []byte -const ( - rsaCertificateFile = "cert.pem" - rsa1024CertificateFile = "rsa_1024_cert.pem" - rsaChainCertificateFile = "rsa_chain_cert.pem" - ecdsaP224CertificateFile = "ecdsa_p224_cert.pem" - ecdsaP256CertificateFile = "ecdsa_p256_cert.pem" - ecdsaP384CertificateFile = "ecdsa_p384_cert.pem" - ecdsaP521CertificateFile = "ecdsa_p521_cert.pem" - ed25519CertificateFile = "ed25519_cert.pem" -) +//go:embed ecdsa_p224_key.pem +var ecdsaP224KeyPEM []byte -const ( - rsaKeyFile = "key.pem" - rsa1024KeyFile = "rsa_1024_key.pem" - rsaChainKeyFile = "rsa_chain_key.pem" - ecdsaP224KeyFile = "ecdsa_p224_key.pem" - ecdsaP256KeyFile = "ecdsa_p256_key.pem" - ecdsaP384KeyFile = "ecdsa_p384_key.pem" - ecdsaP521KeyFile = "ecdsa_p521_key.pem" - ed25519KeyFile = "ed25519_key.pem" - channelIDKeyFile = "channel_id_key.pem" -) +//go:embed ecdsa_p256_key.pem +var ecdsaP256KeyPEM []byte + +//go:embed ecdsa_p384_key.pem +var ecdsaP384KeyPEM []byte + +//go:embed ecdsa_p521_key.pem +var ecdsaP521KeyPEM []byte + +//go:embed ed25519_key.pem +var ed25519KeyPEM []byte + +//go:embed channel_id_key.pem +var channelIDKeyPEM []byte var ( - rsaCertificate Certificate - rsa1024Certificate Certificate - rsaChainCertificate Certificate - ecdsaP224Certificate Certificate - ecdsaP256Certificate Certificate - ecdsaP384Certificate Certificate - ecdsaP521Certificate Certificate - ed25519Certificate Certificate - garbageCertificate Certificate + rsa1024Key rsa.PrivateKey + rsa2048Key rsa.PrivateKey + + ecdsaP224Key ecdsa.PrivateKey + ecdsaP256Key ecdsa.PrivateKey + ecdsaP384Key ecdsa.PrivateKey + ecdsaP521Key ecdsa.PrivateKey + + ed25519Key ed25519.PrivateKey + + channelIDKey ecdsa.PrivateKey ) -var testCerts = []struct { - id testCert - certFile, keyFile string - cert *Certificate -}{ - { - id: testCertRSA, - certFile: rsaCertificateFile, - keyFile: rsaKeyFile, - cert: &rsaCertificate, - }, - { - id: testCertRSA1024, - certFile: rsa1024CertificateFile, - keyFile: rsa1024KeyFile, - cert: &rsa1024Certificate, - }, - { - id: testCertRSAChain, - certFile: rsaChainCertificateFile, - keyFile: rsaChainKeyFile, - cert: &rsaChainCertificate, - }, - { - id: testCertECDSAP224, - certFile: ecdsaP224CertificateFile, - keyFile: ecdsaP224KeyFile, - cert: &ecdsaP224Certificate, - }, - { - id: testCertECDSAP256, - certFile: ecdsaP256CertificateFile, - keyFile: ecdsaP256KeyFile, - cert: &ecdsaP256Certificate, - }, - { - id: testCertECDSAP384, - certFile: ecdsaP384CertificateFile, - keyFile: ecdsaP384KeyFile, - cert: &ecdsaP384Certificate, - }, - { - id: testCertECDSAP521, - certFile: ecdsaP521CertificateFile, - keyFile: ecdsaP521KeyFile, - cert: &ecdsaP521Certificate, - }, - { - id: testCertEd25519, - certFile: ed25519CertificateFile, - keyFile: ed25519KeyFile, - cert: &ed25519Certificate, - }, +var channelIDKeyPath string + +func initKeys() { + // Since key generation is not particularly cheap (especially RSA), and the + // runner is intended to run on systems which may be resouece constrained, + // we load keys from disk instead of dynamically generating them. We treat + // key files the same as dynamically generated certificates, writing them + // out to temporary files before passing them to the shim. + + for _, k := range []struct { + pemBytes []byte + key *rsa.PrivateKey + }{ + {rsa1024KeyPEM, &rsa1024Key}, + {rsa2048KeyPEM, &rsa2048Key}, + } { + key, err := loadPEMKey(k.pemBytes) + if err != nil { + panic(fmt.Sprintf("failed to load RSA test key: %s", err)) + } + *k.key = *(key.(*rsa.PrivateKey)) + } + + for _, k := range []struct { + pemBytes []byte + key *ecdsa.PrivateKey + }{ + {ecdsaP224KeyPEM, &ecdsaP224Key}, + {ecdsaP256KeyPEM, &ecdsaP256Key}, + {ecdsaP384KeyPEM, &ecdsaP384Key}, + {ecdsaP521KeyPEM, &ecdsaP521Key}, + {channelIDKeyPEM, &channelIDKey}, + } { + key, err := loadPEMKey(k.pemBytes) + if err != nil { + panic(fmt.Sprintf("failed to load ECDSA test key: %s", err)) + } + *k.key = *(key.(*ecdsa.PrivateKey)) + } + + k, err := loadPEMKey(ed25519KeyPEM) + if err != nil { + panic(fmt.Sprintf("failed to load Ed25519 test key: %s", err)) + } + ed25519Key = k.(ed25519.PrivateKey) + + channelIDKeyPath = writeTempKeyFile(&channelIDKey) } -var channelIDKey *ecdsa.PrivateKey var channelIDBytes []byte var testOCSPResponse = []byte{1, 2, 3, 4} @@ -231,31 +214,32 @@ var testSCTList2 = []byte{0, 6, 0, 4, 1, 2, 3, 4} var testOCSPExtension = append([]byte{byte(extensionStatusRequest) >> 8, byte(extensionStatusRequest), 0, 8, statusTypeOCSP, 0, 0, 4}, testOCSPResponse...) var testSCTExtension = append([]byte{byte(extensionSignedCertificateTimestamp) >> 8, byte(extensionSignedCertificateTimestamp), 0, byte(len(testSCTList))}, testSCTList...) -func initCertificates() { - for i := range testCerts { - cert, err := LoadX509KeyPair(path.Join(*resourceDir, testCerts[i].certFile), path.Join(*resourceDir, testCerts[i].keyFile)) - if err != nil { - panic(err) - } - cert.OCSPStaple = testOCSPResponse - cert.SignedCertificateTimestampList = testSCTList - *testCerts[i].cert = cert - } +var ( + rsaCertificate CertificateChain + rsaChainCertificate CertificateChain + rsa1024Certificate CertificateChain + ecdsaP224Certificate CertificateChain + ecdsaP256Certificate CertificateChain + ecdsaP384Certificate CertificateChain + ecdsaP521Certificate CertificateChain + ed25519Certificate CertificateChain + garbageCertificate CertificateChain +) - channelIDPEMBlock, err := os.ReadFile(path.Join(*resourceDir, channelIDKeyFile)) - if err != nil { - panic(err) - } - channelIDDERBlock, _ := pem.Decode(channelIDPEMBlock) - if channelIDDERBlock.Type != "EC PRIVATE KEY" { - panic("bad key type") - } - channelIDKey, err = x509.ParseECPrivateKey(channelIDDERBlock.Bytes) - if err != nil { - panic(err) - } - if channelIDKey.Curve != elliptic.P256() { - panic("bad curve") +func initCertificates() { + for _, def := range []struct { + key crypto.Signer + out *CertificateChain + }{ + {&rsa1024Key, &rsa1024Certificate}, + {&rsa2048Key, &rsaCertificate}, + {&ecdsaP224Key, &ecdsaP224Certificate}, + {&ecdsaP256Key, &ecdsaP256Certificate}, + {&ecdsaP384Key, &ecdsaP384Certificate}, + {&ecdsaP521Key, &ecdsaP521Certificate}, + {ed25519Key, &ed25519Certificate}, + } { + *def.out = generateSingleCertChain(nil, def.key, testOCSPResponse, testSCTList) } channelIDBytes = make([]byte, 64) @@ -264,6 +248,31 @@ func initCertificates() { garbageCertificate.Certificate = [][]byte{[]byte("GARBAGE")} garbageCertificate.PrivateKey = rsaCertificate.PrivateKey + + // Build a basic three cert chain for testing chain specific things. + rootTmpl := *baseCertTemplate + rootTmpl.Subject.CommonName = "test root" + rootCert := generateTestCert(&rootTmpl, nil, &rsa2048Key, testOCSPResponse, testSCTList) + intermediateTmpl := *baseCertTemplate + intermediateTmpl.Subject.CommonName = "test inter" + intermediateCert := generateTestCert(&intermediateTmpl, rootCert, &rsa2048Key, testOCSPResponse, testSCTList) + leafTmpl := *baseCertTemplate + leafTmpl.IsCA, leafTmpl.BasicConstraintsValid = false, false + leafCert := generateTestCert(nil, intermediateCert, &rsa2048Key, testOCSPResponse, testSCTList) + + keyPath := writeTempKeyFile(&rsa2048Key) + rootCertPath, chainPath := writeTempCertFile([]*x509.Certificate{rootCert}), writeTempCertFile([]*x509.Certificate{leafCert, intermediateCert}) + + rsaChainCertificate = CertificateChain{ + Certificate: [][]byte{leafCert.Raw, intermediateCert.Raw}, + PrivateKey: &rsa2048Key, + OCSPStaple: testOCSPResponse, + SignedCertificateTimestampList: testSCTList, + Leaf: leafCert, + ChainPath: chainPath, + KeyPath: keyPath, + RootPath: rootCertPath, + } } func flagInts(flagName string, vals []int) []string { @@ -292,38 +301,27 @@ type delegatedCredentialConfig struct { // dcAlgo is the signature scheme that should be used with this delegated // credential. If zero, ECDSA with P-256 is assumed. dcAlgo signatureAlgorithm - // tlsVersion is the version of TLS that should be used with this delegated - // credential. If zero, TLS 1.3 is assumed. - tlsVersion uint16 // algo is the signature algorithm that the delegated credential itself is // signed with. Cannot be zero. algo signatureAlgorithm } -func loadRSAPrivateKey(filename string) (priv *rsa.PrivateKey, privPKCS8 []byte, err error) { - pemPath := path.Join(*resourceDir, filename) - pemBytes, err := os.ReadFile(pemPath) - if err != nil { - return nil, nil, err - } - +func loadPEMKey(pemBytes []byte) (crypto.PrivateKey, error) { block, _ := pem.Decode(pemBytes) if block == nil { - return nil, nil, fmt.Errorf("no PEM block found in %q", pemPath) + return nil, fmt.Errorf("no PEM block found") } - privPKCS8 = block.Bytes - parsed, err := x509.ParsePKCS8PrivateKey(privPKCS8) - if err != nil { - return nil, nil, fmt.Errorf("failed to parse PKCS#8 key from %q", pemPath) + if block.Type != "PRIVATE KEY" { + return nil, fmt.Errorf("unexpected PEM type (expected \"PRIVATE KEY\"): %s", block.Type) } - priv, ok := parsed.(*rsa.PrivateKey) - if !ok { - return nil, nil, fmt.Errorf("found %T in %q rather than an RSA private key", parsed, pemPath) + k, err := x509.ParsePKCS8PrivateKey(block.Bytes) + if err != nil { + return nil, fmt.Errorf("failed to parse PKCS#8 key: %s", err) } - return priv, privPKCS8, nil + return k, nil } func createDelegatedCredential(config delegatedCredentialConfig, parentDER []byte, parentPriv crypto.PrivateKey) (dc, privPKCS8 []uint8, err error) { @@ -336,14 +334,12 @@ func createDelegatedCredential(config delegatedCredentialConfig, parentDER []byt switch dcAlgo { case signatureRSAPKCS1WithMD5, signatureRSAPKCS1WithSHA1, signatureRSAPKCS1WithSHA256, signatureRSAPKCS1WithSHA384, signatureRSAPKCS1WithSHA512, signatureRSAPSSWithSHA256, signatureRSAPSSWithSHA384, signatureRSAPSSWithSHA512: - // RSA keys are expensive to generate so load from disk instead. - var priv *rsa.PrivateKey - if priv, privPKCS8, err = loadRSAPrivateKey(rsaKeyFile); err != nil { + pub = &rsa2048Key.PublicKey + privPKCS8, err = x509.MarshalPKCS8PrivateKey(&rsa2048Key) + if err != nil { return nil, nil, err } - pub = &priv.PublicKey - case signatureECDSAWithSHA1, signatureECDSAWithP256AndSHA256, signatureECDSAWithP384AndSHA384, signatureECDSAWithP521AndSHA512: var curve elliptic.Curve switch dcAlgo { @@ -380,14 +376,6 @@ func createDelegatedCredential(config delegatedCredentialConfig, parentDER []byt if lifetimeSecs > 1<<32 { return nil, nil, fmt.Errorf("lifetime %s is too long to be expressed", lifetime) } - tlsVersion := config.tlsVersion - if tlsVersion == 0 { - tlsVersion = VersionTLS13 - } - - if tlsVersion < VersionTLS13 { - return nil, nil, fmt.Errorf("delegated credentials require TLS 1.3") - } // https://www.rfc-editor.org/rfc/rfc9345.html#section-4 dc = append(dc, byte(lifetimeSecs>>24), byte(lifetimeSecs>>16), byte(lifetimeSecs>>8), byte(lifetimeSecs)) @@ -402,12 +390,7 @@ func createDelegatedCredential(config delegatedCredentialConfig, parentDER []byt dc = append(dc, pubBytes...) var dummyConfig Config - parentSigner, err := getSigner(tlsVersion, parentPriv, &dummyConfig, config.algo, false /* not for verification */) - if err != nil { - return nil, nil, err - } - - parentSignature, err := parentSigner.signMessage(parentPriv, &dummyConfig, delegatedCredentialSignedMessage(dc, config.algo, parentDER)) + parentSignature, err := signMessage(VersionTLS13, parentPriv, &dummyConfig, config.algo, delegatedCredentialSignedMessage(dc, config.algo, parentDER)) if err != nil { return nil, nil, err } @@ -419,33 +402,6 @@ func createDelegatedCredential(config delegatedCredentialConfig, parentDER []byt return dc, privPKCS8, nil } -func getRunnerCertificate(t testCert) Certificate { - for _, cert := range testCerts { - if cert.id == t { - return *cert.cert - } - } - panic("Unknown test certificate") -} - -func getShimCertificate(t testCert) string { - for _, cert := range testCerts { - if cert.id == t { - return cert.certFile - } - } - panic("Unknown test certificate") -} - -func getShimKey(t testCert) string { - for _, cert := range testCerts { - if cert.id == t { - return cert.keyFile - } - } - panic("Unknown test certificate") -} - // recordVersionToWire maps a record-layer protocol version to its wire // representation. func recordVersionToWire(vers uint16, protocol protocol) uint16 { @@ -569,7 +525,7 @@ type connectionExpectations struct { curveID CurveID // peerCertificate, if not nil, is the certificate chain the peer is // expected to send. - peerCertificate *Certificate + peerCertificate *CertificateChain // quicTransportParams contains the QUIC transport parameters that are to be // sent by the peer using codepoint 57. quicTransportParams []byte @@ -608,10 +564,6 @@ type testCase struct { messageLen int // messageCount is the number of test messages that will be sent. messageCount int - // certFile is the path to the certificate to use for the server. - certFile string - // keyFile is the path to the private key to use for the server. - keyFile string // resumeSession controls whether a second connection should be tested // which attempts to resume the first session. resumeSession bool @@ -733,6 +685,9 @@ type testCase struct { // skipVersionNameCheck, if true, will skip the consistency check between // test name and the versions. skipVersionNameCheck bool + // shimCertificate, if populated, is the certificate/chain which should be sent + // by the server/client (this populates the -cert-file and -key-file flags). + shimCertificate *CertificateChain } func (t *testCase) MarshalJSON() ([]byte, error) { @@ -805,17 +760,14 @@ func doExchange(test *testCase, config *Config, conn net.Conn, isResume bool, tr config.ServerSessionCache = NewLRUServerSessionCache(1) } } - if test.testType == clientTest { - if len(config.Certificates) == 0 { - config.Certificates = []Certificate{rsaCertificate} - } - } else { + if test.testType != clientTest { // Supply a ServerName to ensure a constant session cache key, // rather than falling back to net.Conn.RemoteAddr. if len(config.ServerName) == 0 { config.ServerName = "test" } } + if *fuzzer { config.Bugs.NullAllCiphers = true } @@ -1430,6 +1382,9 @@ func doExchanges(test *testCase, shim *shimProcess, resumeCount int, transcripts if test.resumeConfig != nil { resumeConfig = *test.resumeConfig resumeConfig.Rand = config.Rand + if resumeConfig.Chains == nil { + resumeConfig.Chains = config.Chains + } } else { resumeConfig = config } @@ -1503,20 +1458,14 @@ func runTest(dispatcher *shimDispatcher, statusChan chan statusMsg, test *testCa } if test.testType == serverTest { flags = append(flags, "-server") + } - flags = append(flags, "-key-file") - if test.keyFile == "" { - flags = append(flags, path.Join(*resourceDir, rsaKeyFile)) - } else { - flags = append(flags, path.Join(*resourceDir, test.keyFile)) - } - - flags = append(flags, "-cert-file") - if test.certFile == "" { - flags = append(flags, path.Join(*resourceDir, rsaCertificateFile)) - } else { - flags = append(flags, path.Join(*resourceDir, test.certFile)) - } + if test.shimCertificate != nil { + flags = append(flags, "-key-file", test.shimCertificate.KeyPath) + flags = append(flags, "-cert-file", test.shimCertificate.ChainPath) + } else if test.testType == serverTest { + flags = append(flags, "-key-file", rsaCertificate.KeyPath) + flags = append(flags, "-cert-file", rsaCertificate.ChainPath) } if test.protocol == dtls { @@ -1687,6 +1636,19 @@ func runTest(dispatcher *shimDispatcher, statusChan chan statusMsg, test *testCa flags = append(flags, "-write-settings", transcriptPrefix) } + if test.testType == clientTest { + if len(test.config.Chains) == 0 { + test.config.Chains = []CertificateChain{rsaCertificate} + } + + rootFiles := make([]string, 0, len(test.config.Chains)) + for _, c := range test.config.Chains { + rootFiles = append(rootFiles, c.RootPath) + } + + flags = append(flags, "-trust-cert", strings.Join(rootFiles, ",")) + } + flags = append(flags, test.flags...) var env []string @@ -2223,14 +2185,14 @@ read alert 1 0 testType: serverTest, name: "ServerSkipCertificateVerify", config: Config{ - MaxVersion: VersionTLS12, - Certificates: []Certificate{rsaChainCertificate}, + MaxVersion: VersionTLS12, + Chains: []CertificateChain{rsaCertificate}, Bugs: ProtocolBugs{ SkipCertificateVerify: true, }, }, expectations: connectionExpectations{ - peerCertificate: &rsaChainCertificate, + peerCertificate: &rsaCertificate, }, flags: []string{ "-require-any-client-certificate", @@ -3753,14 +3715,14 @@ read alert 1 0 testCases = append(testCases, testCase{ name: "LargeMessage", config: Config{ - Certificates: []Certificate{cert}, + Chains: []CertificateChain{cert}, }, }) testCases = append(testCases, testCase{ protocol: dtls, name: "LargeMessage-DTLS", config: Config{ - Certificates: []Certificate{cert}, + Chains: []CertificateChain{cert}, }, }) @@ -3768,7 +3730,7 @@ read alert 1 0 testCases = append(testCases, testCase{ name: "LargeMessage-Reject", config: Config{ - Certificates: []Certificate{cert}, + Chains: []CertificateChain{cert}, }, flags: []string{"-max-cert-list", "16384"}, shouldFail: true, @@ -3778,7 +3740,7 @@ read alert 1 0 protocol: dtls, name: "LargeMessage-Reject-DTLS", config: Config{ - Certificates: []Certificate{cert}, + Chains: []CertificateChain{cert}, }, flags: []string{"-max-cert-list", "16384"}, shouldFail: true, @@ -3826,17 +3788,11 @@ func addTestForCipherSuite(suite testCipherSuite, ver tlsVersion, protocol proto } prefix := protocol.String() + "-" - var cert Certificate - var certFile string - var keyFile string + var cert CertificateChain if hasComponent(suite.name, "ECDSA") { cert = ecdsaP256Certificate - certFile = ecdsaP256CertificateFile - keyFile = ecdsaP256KeyFile } else { cert = rsaCertificate - certFile = rsaCertificateFile - keyFile = rsaKeyFile } var flags []string @@ -3880,15 +3836,14 @@ func addTestForCipherSuite(suite testCipherSuite, ver tlsVersion, protocol proto MinVersion: ver.version, MaxVersion: ver.version, CipherSuites: []uint16{suite.id}, - Certificates: []Certificate{cert}, + Chains: []CertificateChain{cert}, PreSharedKey: []byte(psk), PreSharedKeyIdentity: pskIdentity, Bugs: ProtocolBugs{ AdvertiseAllConfiguredCiphers: true, }, }, - certFile: certFile, - keyFile: keyFile, + shimCertificate: &cert, flags: flags, resumeSession: true, shouldFail: shouldFail, @@ -3904,7 +3859,7 @@ func addTestForCipherSuite(suite testCipherSuite, ver tlsVersion, protocol proto MinVersion: ver.version, MaxVersion: ver.version, CipherSuites: serverCipherSuites, - Certificates: []Certificate{cert}, + Chains: []CertificateChain{cert}, PreSharedKey: []byte(psk), PreSharedKeyIdentity: pskIdentity, Bugs: ProtocolBugs{ @@ -3931,7 +3886,7 @@ func addTestForCipherSuite(suite testCipherSuite, ver tlsVersion, protocol proto MinVersion: ver.version, MaxVersion: ver.version, CipherSuites: []uint16{suite.id}, - Certificates: []Certificate{cert}, + Chains: []CertificateChain{cert}, PreSharedKey: []byte(psk), PreSharedKeyIdentity: pskIdentity, }, @@ -3958,7 +3913,7 @@ func addTestForCipherSuite(suite testCipherSuite, ver tlsVersion, protocol proto MinVersion: ver.version, MaxVersion: ver.version, CipherSuites: []uint16{suite.id}, - Certificates: []Certificate{cert}, + Chains: []CertificateChain{cert}, PreSharedKey: []byte(psk), PreSharedKeyIdentity: pskIdentity, }, @@ -4098,7 +4053,7 @@ func addCipherSuiteTests() { config: Config{ MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, - Certificates: []Certificate{rsaCertificate}, + Chains: []CertificateChain{rsaCertificate}, Bugs: ProtocolBugs{ SendCipherSuite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, }, @@ -4111,7 +4066,7 @@ func addCipherSuiteTests() { config: Config{ MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, - Certificates: []Certificate{ecdsaP256Certificate}, + Chains: []CertificateChain{ecdsaP256Certificate}, Bugs: ProtocolBugs{ SendCipherSuite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, }, @@ -4124,7 +4079,7 @@ func addCipherSuiteTests() { config: Config{ MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, - Certificates: []Certificate{ed25519Certificate}, + Chains: []CertificateChain{ed25519Certificate}, Bugs: ProtocolBugs{ SendCipherSuite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, }, @@ -4142,12 +4097,9 @@ func addCipherSuiteTests() { MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, }, - flags: []string{ - "-cert-file", path.Join(*resourceDir, rsaCertificateFile), - "-key-file", path.Join(*resourceDir, rsaKeyFile), - }, - shouldFail: true, - expectedError: ":NO_SHARED_CIPHER:", + shimCertificate: &rsaCertificate, + shouldFail: true, + expectedError: ":NO_SHARED_CIPHER:", }) testCases = append(testCases, testCase{ testType: serverTest, @@ -4156,12 +4108,9 @@ func addCipherSuiteTests() { MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, }, - flags: []string{ - "-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile), - "-key-file", path.Join(*resourceDir, ecdsaP256KeyFile), - }, - shouldFail: true, - expectedError: ":NO_SHARED_CIPHER:", + shimCertificate: &ecdsaP256Certificate, + shouldFail: true, + expectedError: ":NO_SHARED_CIPHER:", }) testCases = append(testCases, testCase{ testType: serverTest, @@ -4170,12 +4119,9 @@ func addCipherSuiteTests() { MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, }, - flags: []string{ - "-cert-file", path.Join(*resourceDir, ed25519CertificateFile), - "-key-file", path.Join(*resourceDir, ed25519KeyFile), - }, - shouldFail: true, - expectedError: ":NO_SHARED_CIPHER:", + shimCertificate: &ed25519Certificate, + shouldFail: true, + expectedError: ":NO_SHARED_CIPHER:", }) // Test cipher suite negotiation works as expected. Configure a @@ -4299,7 +4245,7 @@ func addBadECDSASignatureTests() { config: Config{ MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, - Certificates: []Certificate{ecdsaP256Certificate}, + Chains: []CertificateChain{ecdsaP256Certificate}, Bugs: ProtocolBugs{ BadECDSAR: badR, BadECDSAS: badS, @@ -4311,8 +4257,8 @@ func addBadECDSASignatureTests() { testCases = append(testCases, testCase{ name: fmt.Sprintf("BadECDSA-%d-%d-TLS13", badR, badS), config: Config{ - MaxVersion: VersionTLS13, - Certificates: []Certificate{ecdsaP256Certificate}, + MaxVersion: VersionTLS13, + Chains: []CertificateChain{ecdsaP256Certificate}, Bugs: ProtocolBugs{ BadECDSAR: badR, BadECDSAS: badS, @@ -4419,7 +4365,7 @@ func addCBCSplittingTests() { func addClientAuthTests() { // Add a dummy cert pool to stress certificate authority parsing. certPool := x509.NewCertPool() - for _, cert := range []Certificate{rsaCertificate, rsa1024Certificate} { + for _, cert := range []CertificateChain{rsaCertificate, rsa1024Certificate} { cert, err := x509.ParseCertificate(cert.Certificate[0]) if err != nil { panic(err) @@ -4438,18 +4384,15 @@ func addClientAuthTests() { ClientAuth: RequireAnyClientCert, ClientCAs: certPool, }, - flags: []string{ - "-cert-file", path.Join(*resourceDir, rsaCertificateFile), - "-key-file", path.Join(*resourceDir, rsaKeyFile), - }, + shimCertificate: &rsaCertificate, }) testCases = append(testCases, testCase{ testType: serverTest, name: ver.name + "-Server-ClientAuth-RSA", config: Config{ - MinVersion: ver.version, - MaxVersion: ver.version, - Certificates: []Certificate{rsaCertificate}, + MinVersion: ver.version, + MaxVersion: ver.version, + Chains: []CertificateChain{rsaCertificate}, }, flags: []string{"-require-any-client-certificate"}, }) @@ -4457,9 +4400,9 @@ func addClientAuthTests() { testType: serverTest, name: ver.name + "-Server-ClientAuth-ECDSA", config: Config{ - MinVersion: ver.version, - MaxVersion: ver.version, - Certificates: []Certificate{ecdsaP256Certificate}, + MinVersion: ver.version, + MaxVersion: ver.version, + Chains: []CertificateChain{ecdsaP256Certificate}, }, flags: []string{"-require-any-client-certificate"}, }) @@ -4472,10 +4415,7 @@ func addClientAuthTests() { ClientAuth: RequireAnyClientCert, ClientCAs: certPool, }, - flags: []string{ - "-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile), - "-key-file", path.Join(*resourceDir, ecdsaP256KeyFile), - }, + shimCertificate: &ecdsaP256Certificate, }) testCases = append(testCases, testCase{ @@ -4577,7 +4517,7 @@ func addClientAuthTests() { config: Config{ MinVersion: ver.version, MaxVersion: ver.version, - ChannelID: channelIDKey, + ChannelID: &channelIDKey, }, expectations: connectionExpectations{ channelID: true, @@ -4592,9 +4532,9 @@ func addClientAuthTests() { testType: serverTest, name: ver.name + "-Server-CertReq-CA-List", config: Config{ - MinVersion: ver.version, - MaxVersion: ver.version, - Certificates: []Certificate{rsaCertificate}, + MinVersion: ver.version, + MaxVersion: ver.version, + Chains: []CertificateChain{rsaCertificate}, Bugs: ProtocolBugs{ ExpectCertificateReqNames: caNames, }, @@ -4609,15 +4549,14 @@ func addClientAuthTests() { testType: clientTest, name: ver.name + "-Client-CertReq-CA-List", config: Config{ - MinVersion: ver.version, - MaxVersion: ver.version, - Certificates: []Certificate{rsaCertificate}, - ClientAuth: RequireAnyClientCert, - ClientCAs: certPool, + MinVersion: ver.version, + MaxVersion: ver.version, + Chains: []CertificateChain{rsaCertificate}, + ClientAuth: RequireAnyClientCert, + ClientCAs: certPool, }, + shimCertificate: &rsaCertificate, flags: []string{ - "-cert-file", path.Join(*resourceDir, rsaCertificateFile), - "-key-file", path.Join(*resourceDir, rsaKeyFile), "-expect-client-ca-list", encodeDERValues(caNames), }, }) @@ -4633,9 +4572,8 @@ func addClientAuthTests() { PreSharedKey: []byte("secret"), ClientAuth: RequireAnyClientCert, }, + shimCertificate: &rsaCertificate, flags: []string{ - "-cert-file", path.Join(*resourceDir, rsaCertificateFile), - "-key-file", path.Join(*resourceDir, rsaKeyFile), "-psk", "secret", }, shouldFail: true, @@ -4650,9 +4588,8 @@ func addClientAuthTests() { PreSharedKey: []byte("secret"), ClientAuth: RequireAnyClientCert, }, + shimCertificate: &rsaCertificate, flags: []string{ - "-cert-file", path.Join(*resourceDir, rsaCertificateFile), - "-key-file", path.Join(*resourceDir, rsaKeyFile), "-psk", "secret", }, shouldFail: true, @@ -4665,8 +4602,8 @@ func addClientAuthTests() { testType: serverTest, name: "Null-Client-CA-List", config: Config{ - MaxVersion: VersionTLS12, - Certificates: []Certificate{rsaCertificate}, + MaxVersion: VersionTLS12, + Chains: []CertificateChain{rsaCertificate}, Bugs: ProtocolBugs{ ExpectCertificateReqNames: [][]byte{}, }, @@ -4682,8 +4619,8 @@ func addClientAuthTests() { testType: serverTest, name: "TLS13-Empty-Client-CA-List", config: Config{ - MaxVersion: VersionTLS13, - Certificates: []Certificate{rsaCertificate}, + MaxVersion: VersionTLS13, + Chains: []CertificateChain{rsaCertificate}, Bugs: ProtocolBugs{ ExpectNoCertificateAuthoritiesExtension: true, }, @@ -5197,10 +5134,7 @@ func addStateMachineCoverageTests(config stateMachineTestConfig) { MaxVersion: VersionTLS12, ClientAuth: RequireAnyClientCert, }, - flags: []string{ - "-cert-file", path.Join(*resourceDir, rsaCertificateFile), - "-key-file", path.Join(*resourceDir, rsaKeyFile), - }, + shimCertificate: &rsaCertificate, }) } tests = append(tests, testCase{ @@ -5210,10 +5144,7 @@ func addStateMachineCoverageTests(config stateMachineTestConfig) { MaxVersion: VersionTLS13, ClientAuth: RequireAnyClientCert, }, - flags: []string{ - "-cert-file", path.Join(*resourceDir, rsaCertificateFile), - "-key-file", path.Join(*resourceDir, rsaKeyFile), - }, + shimCertificate: &rsaCertificate, }) if config.protocol != quic { tests = append(tests, testCase{ @@ -5223,10 +5154,7 @@ func addStateMachineCoverageTests(config stateMachineTestConfig) { MaxVersion: VersionTLS12, ClientAuth: RequireAnyClientCert, }, - flags: []string{ - "-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile), - "-key-file", path.Join(*resourceDir, ecdsaP256KeyFile), - }, + shimCertificate: &ecdsaP256Certificate, }) } tests = append(tests, testCase{ @@ -5236,10 +5164,7 @@ func addStateMachineCoverageTests(config stateMachineTestConfig) { MaxVersion: VersionTLS13, ClientAuth: RequireAnyClientCert, }, - flags: []string{ - "-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile), - "-key-file", path.Join(*resourceDir, ecdsaP256KeyFile), - }, + shimCertificate: &ecdsaP256Certificate, }) if config.protocol != quic { tests = append(tests, testCase{ @@ -5269,9 +5194,8 @@ func addStateMachineCoverageTests(config stateMachineTestConfig) { MaxVersion: VersionTLS12, ClientAuth: RequireAnyClientCert, }, + shimCertificate: &rsaCertificate, flags: []string{ - "-cert-file", path.Join(*resourceDir, rsaCertificateFile), - "-key-file", path.Join(*resourceDir, rsaKeyFile), "-use-old-client-cert-callback", }, }) @@ -5283,9 +5207,8 @@ func addStateMachineCoverageTests(config stateMachineTestConfig) { MaxVersion: VersionTLS13, ClientAuth: RequireAnyClientCert, }, + shimCertificate: &rsaCertificate, flags: []string{ - "-cert-file", path.Join(*resourceDir, rsaCertificateFile), - "-key-file", path.Join(*resourceDir, rsaKeyFile), "-use-old-client-cert-callback", }, }) @@ -5294,8 +5217,8 @@ func addStateMachineCoverageTests(config stateMachineTestConfig) { testType: serverTest, name: "ClientAuth-Server", config: Config{ - MaxVersion: VersionTLS12, - Certificates: []Certificate{rsaCertificate}, + MaxVersion: VersionTLS12, + Chains: []CertificateChain{rsaCertificate}, }, flags: []string{"-require-any-client-certificate"}, }) @@ -5304,8 +5227,8 @@ func addStateMachineCoverageTests(config stateMachineTestConfig) { testType: serverTest, name: "ClientAuth-Server-TLS13", config: Config{ - MaxVersion: VersionTLS13, - Certificates: []Certificate{rsaCertificate}, + MaxVersion: VersionTLS13, + Chains: []CertificateChain{rsaCertificate}, }, flags: []string{"-require-any-client-certificate"}, }) @@ -5319,10 +5242,7 @@ func addStateMachineCoverageTests(config stateMachineTestConfig) { MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, }, - flags: []string{ - "-cert-file", path.Join(*resourceDir, rsaCertificateFile), - "-key-file", path.Join(*resourceDir, rsaKeyFile), - }, + shimCertificate: &rsaCertificate, }) tests = append(tests, testCase{ testType: serverTest, @@ -5331,10 +5251,7 @@ func addStateMachineCoverageTests(config stateMachineTestConfig) { MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, }, - flags: []string{ - "-cert-file", path.Join(*resourceDir, rsaCertificateFile), - "-key-file", path.Join(*resourceDir, rsaKeyFile), - }, + shimCertificate: &rsaCertificate, }) tests = append(tests, testCase{ testType: serverTest, @@ -5343,10 +5260,7 @@ func addStateMachineCoverageTests(config stateMachineTestConfig) { MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, }, - flags: []string{ - "-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile), - "-key-file", path.Join(*resourceDir, ecdsaP256KeyFile), - }, + shimCertificate: &ecdsaP256Certificate, }) tests = append(tests, testCase{ testType: serverTest, @@ -5355,9 +5269,8 @@ func addStateMachineCoverageTests(config stateMachineTestConfig) { MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, }, + shimCertificate: &ed25519Certificate, flags: []string{ - "-cert-file", path.Join(*resourceDir, ed25519CertificateFile), - "-key-file", path.Join(*resourceDir, ed25519KeyFile), "-verify-prefs", strconv.Itoa(int(signatureEd25519)), }, }) @@ -5440,8 +5353,8 @@ func addStateMachineCoverageTests(config stateMachineTestConfig) { testType: clientTest, name: "ClientOCSPCallback-Pass-" + vers.name, config: Config{ - MaxVersion: vers.version, - Certificates: []Certificate{rsaCertificate}, + MaxVersion: vers.version, + Chains: []CertificateChain{rsaCertificate}, }, flags: []string{ "-enable-ocsp-stapling", @@ -5458,8 +5371,8 @@ func addStateMachineCoverageTests(config stateMachineTestConfig) { testType: clientTest, name: "ClientOCSPCallback-Fail-" + vers.name, config: Config{ - MaxVersion: vers.version, - Certificates: []Certificate{rsaCertificate}, + MaxVersion: vers.version, + Chains: []CertificateChain{rsaCertificate}, }, flags: []string{ "-enable-ocsp-stapling", @@ -5478,8 +5391,8 @@ func addStateMachineCoverageTests(config stateMachineTestConfig) { testType: clientTest, name: "ClientOCSPCallback-FailNoStaple-" + vers.name, config: Config{ - MaxVersion: vers.version, - Certificates: []Certificate{certNoStaple}, + MaxVersion: vers.version, + Chains: []CertificateChain{certNoStaple}, }, flags: []string{ "-enable-ocsp-stapling", @@ -5588,8 +5501,8 @@ func addStateMachineCoverageTests(config stateMachineTestConfig) { testType: testType, name: "CertificateVerificationSucceed" + suffix, config: Config{ - MaxVersion: vers.version, - Certificates: []Certificate{rsaCertificate}, + MaxVersion: vers.version, + Chains: []CertificateChain{rsaCertificate}, }, flags: append([]string{"-expect-verify-result"}, flags...), resumeSession: true, @@ -5598,8 +5511,8 @@ func addStateMachineCoverageTests(config stateMachineTestConfig) { testType: testType, name: "CertificateVerificationFail" + suffix, config: Config{ - MaxVersion: vers.version, - Certificates: []Certificate{rsaCertificate}, + MaxVersion: vers.version, + Chains: []CertificateChain{rsaCertificate}, }, flags: append([]string{"-verify-fail"}, flags...), shouldFail: true, @@ -5611,8 +5524,8 @@ func addStateMachineCoverageTests(config stateMachineTestConfig) { testType: testType, name: "CertificateVerificationDoesNotFailOnResume" + suffix, config: Config{ - MaxVersion: vers.version, - Certificates: []Certificate{rsaCertificate}, + MaxVersion: vers.version, + Chains: []CertificateChain{rsaCertificate}, }, flags: append([]string{"-on-resume-verify-fail"}, flags...), resumeSession: true, @@ -5622,8 +5535,8 @@ func addStateMachineCoverageTests(config stateMachineTestConfig) { testType: testType, name: "CertificateVerificationFailsOnResume" + suffix, config: Config{ - MaxVersion: vers.version, - Certificates: []Certificate{rsaCertificate}, + MaxVersion: vers.version, + Chains: []CertificateChain{rsaCertificate}, }, flags: append([]string{ "-on-resume-verify-fail", @@ -5638,8 +5551,8 @@ func addStateMachineCoverageTests(config stateMachineTestConfig) { testType: testType, name: "CertificateVerificationPassesOnResume" + suffix, config: Config{ - MaxVersion: vers.version, - Certificates: []Certificate{rsaCertificate}, + MaxVersion: vers.version, + Chains: []CertificateChain{rsaCertificate}, }, flags: append([]string{ "-reverify-on-resume", @@ -5769,8 +5682,8 @@ func addStateMachineCoverageTests(config stateMachineTestConfig) { testType: clientTest, name: "CertificateVerificationSoftFail-" + vers.name, config: Config{ - MaxVersion: vers.version, - Certificates: []Certificate{rsaCertificate}, + MaxVersion: vers.version, + Chains: []CertificateChain{rsaCertificate}, }, flags: []string{ "-verify-fail", @@ -5967,7 +5880,7 @@ read alert 1 0 NextProtos: []string{"foo"}, }, flags: []string{ - "-send-channel-id", path.Join(*resourceDir, channelIDKeyFile), + "-send-channel-id", channelIDKeyPath, "-select-next-proto", "foo", }, resumeSession: true, @@ -5982,7 +5895,7 @@ read alert 1 0 name: "ChannelID-NPN-Server", config: Config{ MaxVersion: VersionTLS12, - ChannelID: channelIDKey, + ChannelID: &channelIDKey, NextProtos: []string{"bar"}, }, flags: []string{ @@ -6023,7 +5936,7 @@ read alert 1 0 MaxVersion: ver.version, RequestChannelID: true, }, - flags: []string{"-send-channel-id", path.Join(*resourceDir, channelIDKeyFile)}, + flags: []string{"-send-channel-id", channelIDKeyPath}, resumeSession: true, expectations: connectionExpectations{ channelID: true, @@ -6036,7 +5949,7 @@ read alert 1 0 name: "ChannelID-Server-" + ver.name, config: Config{ MaxVersion: ver.version, - ChannelID: channelIDKey, + ChannelID: &channelIDKey, }, flags: []string{ "-expect-channel-id", @@ -6053,7 +5966,7 @@ read alert 1 0 name: "InvalidChannelIDSignature-" + ver.name, config: Config{ MaxVersion: ver.version, - ChannelID: channelIDKey, + ChannelID: &channelIDKey, Bugs: ProtocolBugs{ InvalidChannelIDSignature: true, }, @@ -6071,7 +5984,7 @@ read alert 1 0 config: Config{ MaxVersion: ver.version, CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, - ChannelID: channelIDKey, + ChannelID: &channelIDKey, }, expectations: connectionExpectations{ channelID: false, @@ -6086,7 +5999,7 @@ read alert 1 0 config: Config{ MaxVersion: ver.version, CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, - ChannelID: channelIDKey, + ChannelID: &channelIDKey, }, expectations: connectionExpectations{ channelID: false, @@ -8620,7 +8533,7 @@ func addExtensionTests() { resumeSession: true, }) - emptySCTListCert := *testCerts[0].cert + emptySCTListCert := rsaCertificate emptySCTListCert.SignedCertificateTimestampList = []byte{0, 0} // Test empty SCT list. @@ -8629,8 +8542,8 @@ func addExtensionTests() { name: "SignedCertificateTimestampListEmpty-Client-" + suffix, testType: clientTest, config: Config{ - MaxVersion: ver.version, - Certificates: []Certificate{emptySCTListCert}, + MaxVersion: ver.version, + Chains: []CertificateChain{emptySCTListCert}, }, flags: []string{ "-enable-signed-cert-timestamps", @@ -8639,7 +8552,7 @@ func addExtensionTests() { expectedError: ":ERROR_PARSING_EXTENSION:", }) - emptySCTCert := *testCerts[0].cert + emptySCTCert := rsaCertificate emptySCTCert.SignedCertificateTimestampList = []byte{0, 6, 0, 2, 1, 2, 0, 0} // Test empty SCT in non-empty list. @@ -8648,8 +8561,8 @@ func addExtensionTests() { name: "SignedCertificateTimestampListEmptySCT-Client-" + suffix, testType: clientTest, config: Config{ - MaxVersion: ver.version, - Certificates: []Certificate{emptySCTCert}, + MaxVersion: ver.version, + Chains: []CertificateChain{emptySCTCert}, }, flags: []string{ "-enable-signed-cert-timestamps", @@ -8881,8 +8794,8 @@ func addExtensionTests() { name: "SendExtensionOnClientCertificate-TLS13", testType: serverTest, config: Config{ - MaxVersion: VersionTLS13, - Certificates: []Certificate{rsaCertificate}, + MaxVersion: VersionTLS13, + Chains: []CertificateChain{rsaCertificate}, Bugs: ProtocolBugs{ SendExtensionOnCertificate: testOCSPExtension, }, @@ -8911,8 +8824,8 @@ func addExtensionTests() { testCases = append(testCases, testCase{ name: "IgnoreExtensionsOnIntermediates-TLS13", config: Config{ - MaxVersion: VersionTLS13, - Certificates: []Certificate{rsaChainCertificate}, + MaxVersion: VersionTLS13, + Chains: []CertificateChain{rsaChainCertificate}, Bugs: ProtocolBugs{ // Send different values on the intermediate. This tests // the intermediate's extensions do not override the @@ -8943,9 +8856,8 @@ func addExtensionTests() { ExpectNoExtensionsOnIntermediate: true, }, }, + shimCertificate: &rsaChainCertificate, flags: []string{ - "-cert-file", path.Join(*resourceDir, rsaChainCertificateFile), - "-key-file", path.Join(*resourceDir, rsaChainKeyFile), "-ocsp-response", base64FlagValue(testOCSPResponse), "-signed-cert-timestamps", @@ -8960,9 +8872,8 @@ func addExtensionTests() { MaxVersion: VersionTLS13, ClientAuth: RequireAnyClientCert, }, + shimCertificate: &rsaCertificate, flags: []string{ - "-cert-file", path.Join(*resourceDir, rsaCertificateFile), - "-key-file", path.Join(*resourceDir, rsaKeyFile), "-ocsp-response", base64FlagValue(testOCSPResponse), "-signed-cert-timestamps", @@ -9975,8 +9886,8 @@ func addRenegotiationTests() { testCases = append(testCases, testCase{ name: "Renegotiation-CertificateChange", config: Config{ - MaxVersion: VersionTLS12, - Certificates: []Certificate{rsaCertificate}, + MaxVersion: VersionTLS12, + Chains: []CertificateChain{rsaCertificate}, Bugs: ProtocolBugs{ RenegotiationCertificate: &rsaChainCertificate, }, @@ -9989,8 +9900,8 @@ func addRenegotiationTests() { testCases = append(testCases, testCase{ name: "Renegotiation-CertificateChange-2", config: Config{ - MaxVersion: VersionTLS12, - Certificates: []Certificate{rsaCertificate}, + MaxVersion: VersionTLS12, + Chains: []CertificateChain{rsaCertificate}, Bugs: ProtocolBugs{ RenegotiationCertificate: &rsa1024Certificate, }, @@ -10099,30 +10010,30 @@ func addDTLSReplayTests() { var testSignatureAlgorithms = []struct { name string id signatureAlgorithm - cert testCert + cert *CertificateChain // If non-zero, the curve that must be supported in TLS 1.2 for cert to be // accepted. curve CurveID }{ - {"RSA_PKCS1_SHA1", signatureRSAPKCS1WithSHA1, testCertRSA, 0}, - {"RSA_PKCS1_SHA256", signatureRSAPKCS1WithSHA256, testCertRSA, 0}, - {"RSA_PKCS1_SHA384", signatureRSAPKCS1WithSHA384, testCertRSA, 0}, - {"RSA_PKCS1_SHA512", signatureRSAPKCS1WithSHA512, testCertRSA, 0}, - {"ECDSA_SHA1", signatureECDSAWithSHA1, testCertECDSAP256, CurveP256}, + {"RSA_PKCS1_SHA1", signatureRSAPKCS1WithSHA1, &rsaCertificate, 0}, + {"RSA_PKCS1_SHA256", signatureRSAPKCS1WithSHA256, &rsaCertificate, 0}, + {"RSA_PKCS1_SHA384", signatureRSAPKCS1WithSHA384, &rsaCertificate, 0}, + {"RSA_PKCS1_SHA512", signatureRSAPKCS1WithSHA512, &rsaCertificate, 0}, + {"ECDSA_SHA1", signatureECDSAWithSHA1, &ecdsaP256Certificate, CurveP256}, // The “P256” in the following line is not a mistake. In TLS 1.2 the // hash function doesn't have to match the curve and so the same // signature algorithm works with P-224. - {"ECDSA_P224_SHA256", signatureECDSAWithP256AndSHA256, testCertECDSAP224, CurveP224}, - {"ECDSA_P256_SHA256", signatureECDSAWithP256AndSHA256, testCertECDSAP256, CurveP256}, - {"ECDSA_P384_SHA384", signatureECDSAWithP384AndSHA384, testCertECDSAP384, CurveP384}, - {"ECDSA_P521_SHA512", signatureECDSAWithP521AndSHA512, testCertECDSAP521, CurveP521}, - {"RSA_PSS_SHA256", signatureRSAPSSWithSHA256, testCertRSA, 0}, - {"RSA_PSS_SHA384", signatureRSAPSSWithSHA384, testCertRSA, 0}, - {"RSA_PSS_SHA512", signatureRSAPSSWithSHA512, testCertRSA, 0}, - {"Ed25519", signatureEd25519, testCertEd25519, 0}, + {"ECDSA_P224_SHA256", signatureECDSAWithP256AndSHA256, &ecdsaP224Certificate, CurveP224}, + {"ECDSA_P256_SHA256", signatureECDSAWithP256AndSHA256, &ecdsaP256Certificate, CurveP256}, + {"ECDSA_P384_SHA384", signatureECDSAWithP384AndSHA384, &ecdsaP384Certificate, CurveP384}, + {"ECDSA_P521_SHA512", signatureECDSAWithP521AndSHA512, &ecdsaP521Certificate, CurveP521}, + {"RSA_PSS_SHA256", signatureRSAPSSWithSHA256, &rsaCertificate, 0}, + {"RSA_PSS_SHA384", signatureRSAPSSWithSHA384, &rsaCertificate, 0}, + {"RSA_PSS_SHA512", signatureRSAPSSWithSHA512, &rsaCertificate, 0}, + {"Ed25519", signatureEd25519, &ed25519Certificate, 0}, // Tests for key types prior to TLS 1.2. - {"RSA", 0, testCertRSA, 0}, - {"ECDSA", 0, testCertECDSAP256, CurveP256}, + {"RSA", 0, &rsaCertificate, 0}, + {"ECDSA", 0, &ecdsaP256Certificate, CurveP256}, } const fakeSigAlg1 signatureAlgorithm = 0x2a01 @@ -10165,7 +10076,7 @@ func addSignatureAlgorithmTests() { } // SHA-224 has been removed from TLS 1.3 and, in 1.3, // the curve has to match the hash size. - if ver.version >= VersionTLS13 && alg.cert == testCertECDSAP224 { + if ver.version >= VersionTLS13 && alg.curve == CurveP224 { shouldFail = true } @@ -10215,13 +10126,8 @@ func addSignatureAlgorithmTests() { fakeSigAlg2, }, }, - flags: append( - []string{ - "-cert-file", path.Join(*resourceDir, getShimCertificate(alg.cert)), - "-key-file", path.Join(*resourceDir, getShimKey(alg.cert)), - }, - curveFlags..., - ), + shimCertificate: alg.cert, + flags: curveFlags, shouldFail: shouldFail, expectedError: signError, expectedLocalError: signLocalError, @@ -10239,13 +10145,8 @@ func addSignatureAlgorithmTests() { MaxVersion: ver.version, VerifySignatureAlgorithms: allAlgorithms, }, - flags: append( - []string{ - "-cert-file", path.Join(*resourceDir, getShimCertificate(alg.cert)), - "-key-file", path.Join(*resourceDir, getShimKey(alg.cert)), - }, - curveFlags..., - ), + shimCertificate: alg.cert, + flags: curveFlags, expectations: connectionExpectations{ peerSignatureAlgorithm: alg.id, }, @@ -10273,8 +10174,8 @@ func addSignatureAlgorithmTests() { testType: testType, name: prefix + "Verify" + suffix, config: Config{ - MaxVersion: ver.version, - Certificates: []Certificate{getRunnerCertificate(alg.cert)}, + MaxVersion: ver.version, + Chains: []CertificateChain{*alg.cert}, SignSignatureAlgorithms: []signatureAlgorithm{ alg.id, }, @@ -10304,8 +10205,8 @@ func addSignatureAlgorithmTests() { testType: testType, name: prefix + "VerifyDefault" + suffix, config: Config{ - MaxVersion: ver.version, - Certificates: []Certificate{getRunnerCertificate(alg.cert)}, + MaxVersion: ver.version, + Chains: []CertificateChain{*alg.cert}, SignSignatureAlgorithms: []signatureAlgorithm{ alg.id, }, @@ -10333,8 +10234,8 @@ func addSignatureAlgorithmTests() { testType: testType, name: prefix + "InvalidSignature" + suffix, config: Config{ - MaxVersion: ver.version, - Certificates: []Certificate{getRunnerCertificate(alg.cert)}, + MaxVersion: ver.version, + Chains: []CertificateChain{*alg.cert}, SignSignatureAlgorithms: []signatureAlgorithm{ alg.id, }, @@ -10386,9 +10287,8 @@ func addSignatureAlgorithmTests() { signatureECDSAWithP256AndSHA256, }, }, + shimCertificate: &rsaCertificate, flags: []string{ - "-cert-file", path.Join(*resourceDir, rsaCertificateFile), - "-key-file", path.Join(*resourceDir, rsaKeyFile), "-expect-peer-verify-pref", strconv.Itoa(int(signatureRSAPSSWithSHA256)), "-expect-peer-verify-pref", strconv.Itoa(int(signatureEd25519)), "-expect-peer-verify-pref", strconv.Itoa(int(signatureECDSAWithP256AndSHA256)), @@ -10406,9 +10306,8 @@ func addSignatureAlgorithmTests() { signatureECDSAWithP256AndSHA256, }, }, + shimCertificate: &rsaCertificate, flags: []string{ - "-cert-file", path.Join(*resourceDir, rsaCertificateFile), - "-key-file", path.Join(*resourceDir, rsaKeyFile), "-expect-peer-verify-pref", strconv.Itoa(int(signatureRSAPSSWithSHA256)), "-expect-peer-verify-pref", strconv.Itoa(int(signatureEd25519)), "-expect-peer-verify-pref", strconv.Itoa(int(signatureECDSAWithP256AndSHA256)), @@ -10429,10 +10328,7 @@ func addSignatureAlgorithmTests() { signatureECDSAWithSHA1, }, }, - flags: []string{ - "-cert-file", path.Join(*resourceDir, rsaCertificateFile), - "-key-file", path.Join(*resourceDir, rsaKeyFile), - }, + shimCertificate: &rsaCertificate, expectations: connectionExpectations{ peerSignatureAlgorithm: signatureRSAPKCS1WithSHA384, }, @@ -10450,10 +10346,7 @@ func addSignatureAlgorithmTests() { signatureECDSAWithSHA1, }, }, - flags: []string{ - "-cert-file", path.Join(*resourceDir, rsaCertificateFile), - "-key-file", path.Join(*resourceDir, rsaKeyFile), - }, + shimCertificate: &rsaCertificate, expectations: connectionExpectations{ peerSignatureAlgorithm: signatureRSAPSSWithSHA384, }, @@ -10498,8 +10391,8 @@ func addSignatureAlgorithmTests() { testType: serverTest, name: "Verify-ClientAuth-SignatureType", config: Config{ - MaxVersion: VersionTLS12, - Certificates: []Certificate{rsaCertificate}, + MaxVersion: VersionTLS12, + Chains: []CertificateChain{rsaCertificate}, SignSignatureAlgorithms: []signatureAlgorithm{ signatureRSAPKCS1WithSHA256, }, @@ -10518,8 +10411,8 @@ func addSignatureAlgorithmTests() { testType: serverTest, name: "Verify-ClientAuth-SignatureType-TLS13", config: Config{ - MaxVersion: VersionTLS13, - Certificates: []Certificate{rsaCertificate}, + MaxVersion: VersionTLS13, + Chains: []CertificateChain{rsaCertificate}, SignSignatureAlgorithms: []signatureAlgorithm{ signatureRSAPSSWithSHA256, }, @@ -10579,10 +10472,7 @@ func addSignatureAlgorithmTests() { NoSignatureAlgorithms: true, }, }, - flags: []string{ - "-cert-file", path.Join(*resourceDir, rsaCertificateFile), - "-key-file", path.Join(*resourceDir, rsaKeyFile), - }, + shimCertificate: &rsaCertificate, }) testCases = append(testCases, testCase{ @@ -10597,10 +10487,7 @@ func addSignatureAlgorithmTests() { NoSignatureAlgorithms: true, }, }, - flags: []string{ - "-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile), - "-key-file", path.Join(*resourceDir, ecdsaP256KeyFile), - }, + shimCertificate: &ecdsaP256Certificate, }) testCases = append(testCases, testCase{ @@ -10634,10 +10521,7 @@ func addSignatureAlgorithmTests() { NoSignatureAlgorithms: true, }, }, - flags: []string{ - "-cert-file", path.Join(*resourceDir, rsaCertificateFile), - "-key-file", path.Join(*resourceDir, rsaKeyFile), - }, + shimCertificate: &rsaCertificate, shouldFail: true, expectedError: ":DECODE_ERROR:", expectedLocalError: "remote error: error decoding message", @@ -10655,10 +10539,7 @@ func addSignatureAlgorithmTests() { NoSignatureAlgorithms: true, }, }, - flags: []string{ - "-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile), - "-key-file", path.Join(*resourceDir, ecdsaP256KeyFile), - }, + shimCertificate: &ecdsaP256Certificate, shouldFail: true, expectedError: ":DECODE_ERROR:", expectedLocalError: "remote error: error decoding message", @@ -10676,10 +10557,7 @@ func addSignatureAlgorithmTests() { NoSignatureAlgorithms: true, }, }, - flags: []string{ - "-cert-file", path.Join(*resourceDir, rsaCertificateFile), - "-key-file", path.Join(*resourceDir, rsaKeyFile), - }, + shimCertificate: &rsaCertificate, shouldFail: true, expectedError: ":DECODE_ERROR:", expectedLocalError: "remote error: error decoding message", @@ -10691,8 +10569,8 @@ func addSignatureAlgorithmTests() { testType: serverTest, name: "ClientAuth-Enforced", config: Config{ - MaxVersion: VersionTLS12, - Certificates: []Certificate{rsaCertificate}, + MaxVersion: VersionTLS12, + Chains: []CertificateChain{rsaCertificate}, SignSignatureAlgorithms: []signatureAlgorithm{ signatureRSAPKCS1WithMD5, }, @@ -10724,8 +10602,8 @@ func addSignatureAlgorithmTests() { testType: serverTest, name: "ClientAuth-Enforced-TLS13", config: Config{ - MaxVersion: VersionTLS13, - Certificates: []Certificate{rsaCertificate}, + MaxVersion: VersionTLS13, + Chains: []CertificateChain{rsaCertificate}, SignSignatureAlgorithms: []signatureAlgorithm{ signatureRSAPKCS1WithMD5, }, @@ -10767,9 +10645,8 @@ func addSignatureAlgorithmTests() { signatureRSAPKCS1WithSHA1, }, }, + shimCertificate: &rsaCertificate, flags: []string{ - "-cert-file", path.Join(*resourceDir, rsaCertificateFile), - "-key-file", path.Join(*resourceDir, rsaKeyFile), "-signing-prefs", strconv.Itoa(int(signatureRSAPKCS1WithSHA256)), }, shouldFail: true, @@ -10785,9 +10662,8 @@ func addSignatureAlgorithmTests() { signatureRSAPSSWithSHA384, }, }, + shimCertificate: &rsaCertificate, flags: []string{ - "-cert-file", path.Join(*resourceDir, rsaCertificateFile), - "-key-file", path.Join(*resourceDir, rsaKeyFile), "-signing-prefs", strconv.Itoa(int(signatureRSAPSSWithSHA256)), }, shouldFail: true, @@ -10803,9 +10679,8 @@ func addSignatureAlgorithmTests() { signatureRSAPKCS1WithSHA256, }, }, + shimCertificate: &rsaCertificate, flags: []string{ - "-cert-file", path.Join(*resourceDir, rsaCertificateFile), - "-key-file", path.Join(*resourceDir, rsaKeyFile), "-signing-prefs", strconv.Itoa(int(signatureRSAPKCS1WithSHA256)), "-signing-prefs", strconv.Itoa(int(signatureRSAPKCS1WithSHA1)), }, @@ -10822,9 +10697,8 @@ func addSignatureAlgorithmTests() { signatureRSAPKCS1WithSHA1, }, }, + shimCertificate: &rsaCertificate, flags: []string{ - "-cert-file", path.Join(*resourceDir, rsaCertificateFile), - "-key-file", path.Join(*resourceDir, rsaKeyFile), "-signing-prefs", strconv.Itoa(int(signatureRSAPKCS1WithSHA512)), "-signing-prefs", strconv.Itoa(int(signatureRSAPKCS1WithSHA256)), "-signing-prefs", strconv.Itoa(int(signatureRSAPKCS1WithSHA1)), @@ -10845,10 +10719,7 @@ func addSignatureAlgorithmTests() { signatureECDSAWithSHA1, }, }, - flags: []string{ - "-cert-file", path.Join(*resourceDir, rsaCertificateFile), - "-key-file", path.Join(*resourceDir, rsaKeyFile), - }, + shimCertificate: &rsaCertificate, expectations: connectionExpectations{ peerSignatureAlgorithm: signatureRSAPKCS1WithSHA256, }, @@ -10865,9 +10736,8 @@ func addSignatureAlgorithmTests() { signatureRSAPKCS1WithSHA256, }, }, + shimCertificate: &rsaCertificate, flags: []string{ - "-cert-file", path.Join(*resourceDir, rsaCertificateFile), - "-key-file", path.Join(*resourceDir, rsaKeyFile), "-signing-prefs", strconv.Itoa(int(signatureECDSAWithP256AndSHA256)), "-signing-prefs", strconv.Itoa(int(signatureRSAPKCS1WithSHA256)), }, @@ -10883,7 +10753,7 @@ func addSignatureAlgorithmTests() { config: Config{ MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, - Certificates: []Certificate{ecdsaP256Certificate}, + Chains: []CertificateChain{ecdsaP256Certificate}, }, flags: []string{"-curves", strconv.Itoa(int(CurveP384))}, shouldFail: true, @@ -10894,8 +10764,8 @@ func addSignatureAlgorithmTests() { testCases = append(testCases, testCase{ name: "CheckLeafCurve-TLS13", config: Config{ - MaxVersion: VersionTLS13, - Certificates: []Certificate{ecdsaP256Certificate}, + MaxVersion: VersionTLS13, + Chains: []CertificateChain{ecdsaP256Certificate}, }, flags: []string{"-curves", strconv.Itoa(int(CurveP384))}, }) @@ -10906,7 +10776,7 @@ func addSignatureAlgorithmTests() { config: Config{ MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, - Certificates: []Certificate{ecdsaP256Certificate}, + Chains: []CertificateChain{ecdsaP256Certificate}, SignSignatureAlgorithms: []signatureAlgorithm{ signatureECDSAWithP384AndSHA384, }, @@ -10917,8 +10787,8 @@ func addSignatureAlgorithmTests() { testCases = append(testCases, testCase{ name: "ECDSACurveMismatch-Verify-TLS13", config: Config{ - MaxVersion: VersionTLS13, - Certificates: []Certificate{ecdsaP256Certificate}, + MaxVersion: VersionTLS13, + Chains: []CertificateChain{ecdsaP256Certificate}, SignSignatureAlgorithms: []signatureAlgorithm{ signatureECDSAWithP384AndSHA384, }, @@ -10942,10 +10812,7 @@ func addSignatureAlgorithmTests() { signatureECDSAWithP256AndSHA256, }, }, - flags: []string{ - "-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile), - "-key-file", path.Join(*resourceDir, ecdsaP256KeyFile), - }, + shimCertificate: &ecdsaP256Certificate, expectations: connectionExpectations{ peerSignatureAlgorithm: signatureECDSAWithP256AndSHA256, }, @@ -10962,12 +10829,9 @@ func addSignatureAlgorithmTests() { signatureRSAPSSWithSHA512, }, }, - flags: []string{ - "-cert-file", path.Join(*resourceDir, rsa1024CertificateFile), - "-key-file", path.Join(*resourceDir, rsa1024KeyFile), - }, - shouldFail: true, - expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", + shimCertificate: &rsa1024Certificate, + shouldFail: true, + expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", }) // Test that RSA-PSS is enabled by default for TLS 1.2. @@ -11001,8 +10865,8 @@ func addSignatureAlgorithmTests() { testType: clientTest, name: "NoEd25519-TLS11-ServerAuth-Verify", config: Config{ - MaxVersion: VersionTLS11, - Certificates: []Certificate{ed25519Certificate}, + MaxVersion: VersionTLS11, + Chains: []CertificateChain{ed25519Certificate}, Bugs: ProtocolBugs{ // Sign with Ed25519 even though it is TLS 1.1. SigningAlgorithmForLegacyVersions: signatureEd25519, @@ -11019,8 +10883,8 @@ func addSignatureAlgorithmTests() { MaxVersion: VersionTLS11, }, flags: []string{ - "-cert-file", path.Join(*resourceDir, ed25519CertificateFile), - "-key-file", path.Join(*resourceDir, ed25519KeyFile), + "-cert-file", ed25519Certificate.ChainPath, + "-key-file", ed25519Certificate.KeyPath, }, shouldFail: true, expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", @@ -11029,8 +10893,8 @@ func addSignatureAlgorithmTests() { testType: serverTest, name: "NoEd25519-TLS11-ClientAuth-Verify", config: Config{ - MaxVersion: VersionTLS11, - Certificates: []Certificate{ed25519Certificate}, + MaxVersion: VersionTLS11, + Chains: []CertificateChain{ed25519Certificate}, Bugs: ProtocolBugs{ // Sign with Ed25519 even though it is TLS 1.1. SigningAlgorithmForLegacyVersions: signatureEd25519, @@ -11050,12 +10914,9 @@ func addSignatureAlgorithmTests() { MaxVersion: VersionTLS11, ClientAuth: RequireAnyClientCert, }, - flags: []string{ - "-cert-file", path.Join(*resourceDir, ed25519CertificateFile), - "-key-file", path.Join(*resourceDir, ed25519KeyFile), - }, - shouldFail: true, - expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", + shimCertificate: &ed25519Certificate, + shouldFail: true, + expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", }) // Test Ed25519 is not advertised by default. @@ -11063,7 +10924,7 @@ func addSignatureAlgorithmTests() { testType: clientTest, name: "Ed25519DefaultDisable-NoAdvertise", config: Config{ - Certificates: []Certificate{ed25519Certificate}, + Chains: []CertificateChain{ed25519Certificate}, }, shouldFail: true, expectedLocalError: "tls: no common signature algorithms", @@ -11075,7 +10936,7 @@ func addSignatureAlgorithmTests() { testType: clientTest, name: "Ed25519DefaultDisable-NoAccept", config: Config{ - Certificates: []Certificate{ed25519Certificate}, + Chains: []CertificateChain{ed25519Certificate}, Bugs: ProtocolBugs{ IgnorePeerSignatureAlgorithmPreferences: true, }, @@ -11090,7 +10951,7 @@ func addSignatureAlgorithmTests() { testCases = append(testCases, testCase{ name: "VerifyPreferences-Advertised", config: Config{ - Certificates: []Certificate{rsaCertificate}, + Chains: []CertificateChain{rsaCertificate}, SignSignatureAlgorithms: []signatureAlgorithm{ signatureRSAPSSWithSHA256, signatureRSAPSSWithSHA384, @@ -11108,7 +10969,7 @@ func addSignatureAlgorithmTests() { testCases = append(testCases, testCase{ name: "VerifyPreferences-NoCommonAlgorithms", config: Config{ - Certificates: []Certificate{rsaCertificate}, + Chains: []CertificateChain{rsaCertificate}, SignSignatureAlgorithms: []signatureAlgorithm{ signatureRSAPSSWithSHA256, signatureRSAPSSWithSHA512, @@ -11125,7 +10986,7 @@ func addSignatureAlgorithmTests() { testCases = append(testCases, testCase{ name: "VerifyPreferences-Enforced", config: Config{ - Certificates: []Certificate{rsaCertificate}, + Chains: []CertificateChain{rsaCertificate}, SignSignatureAlgorithms: []signatureAlgorithm{ signatureRSAPSSWithSHA256, signatureRSAPSSWithSHA512, @@ -11147,7 +11008,7 @@ func addSignatureAlgorithmTests() { testCases = append(testCases, testCase{ name: "VerifyPreferences-Ed25519", config: Config{ - Certificates: []Certificate{ed25519Certificate}, + Chains: []CertificateChain{ed25519Certificate}, }, flags: []string{ "-verify-prefs", strconv.Itoa(int(signatureEd25519)), @@ -11176,9 +11037,8 @@ func addSignatureAlgorithmTests() { ClientAuth: RequireAnyClientCert, VerifySignatureAlgorithms: []signatureAlgorithm{signatureRSAPKCS1WithMD5AndSHA1}, }, + shimCertificate: &rsaCertificate, flags: []string{ - "-cert-file", path.Join(*resourceDir, rsaCertificateFile), - "-key-file", path.Join(*resourceDir, rsaKeyFile), "-signing-prefs", strconv.Itoa(int(signatureRSAPKCS1WithMD5AndSHA1)), // Include a valid algorithm as well, to avoid an empty list // if filtered out. @@ -11194,17 +11054,16 @@ func addSignatureAlgorithmTests() { testType: testType, name: prefix + "NoVerify-RSA_PKCS1_MD5_SHA1", config: Config{ - MaxVersion: ver.version, - Certificates: []Certificate{rsaCertificate}, + MaxVersion: ver.version, + Chains: []CertificateChain{rsaCertificate}, Bugs: ProtocolBugs{ IgnorePeerSignatureAlgorithmPreferences: true, AlwaysSignAsLegacyVersion: true, SendSignatureAlgorithm: signatureRSAPKCS1WithMD5AndSHA1, }, }, + shimCertificate: &rsaCertificate, flags: []string{ - "-cert-file", path.Join(*resourceDir, rsaCertificateFile), - "-key-file", path.Join(*resourceDir, rsaKeyFile), "-verify-prefs", strconv.Itoa(int(signatureRSAPKCS1WithMD5AndSHA1)), // Include a valid algorithm as well, to avoid an empty list // if filtered out. @@ -13495,8 +13354,8 @@ func makePerMessageTests() []perMessageTest { protocol: protocol, name: "ClientCertificate" + suffix, config: Config{ - Certificates: []Certificate{rsaCertificate}, - MaxVersion: VersionTLS12, + Chains: []CertificateChain{rsaCertificate}, + MaxVersion: VersionTLS12, }, flags: []string{"-require-any-client-certificate"}, }, @@ -13509,8 +13368,8 @@ func makePerMessageTests() []perMessageTest { protocol: protocol, name: "CertificateVerify" + suffix, config: Config{ - Certificates: []Certificate{rsaCertificate}, - MaxVersion: VersionTLS12, + Chains: []CertificateChain{rsaCertificate}, + MaxVersion: VersionTLS12, }, flags: []string{"-require-any-client-certificate"}, }, @@ -13551,7 +13410,7 @@ func makePerMessageTests() []perMessageTest { name: "ChannelID" + suffix, config: Config{ MaxVersion: VersionTLS12, - ChannelID: channelIDKey, + ChannelID: &channelIDKey, }, flags: []string{ "-expect-channel-id", @@ -13685,8 +13544,8 @@ func makePerMessageTests() []perMessageTest { protocol: protocol, name: "TLS13-ClientCertificate" + suffix, config: Config{ - Certificates: []Certificate{rsaCertificate}, - MaxVersion: VersionTLS13, + Chains: []CertificateChain{rsaCertificate}, + MaxVersion: VersionTLS13, }, flags: []string{"-require-any-client-certificate"}, }, @@ -13699,8 +13558,8 @@ func makePerMessageTests() []perMessageTest { protocol: protocol, name: "TLS13-ClientCertificateVerify" + suffix, config: Config{ - Certificates: []Certificate{rsaCertificate}, - MaxVersion: VersionTLS13, + Chains: []CertificateChain{rsaCertificate}, + MaxVersion: VersionTLS13, }, flags: []string{"-require-any-client-certificate"}, }, @@ -14595,12 +14454,9 @@ func addTLS13HandshakeTests() { SendRequestContext: []byte("request context"), }, }, - flags: []string{ - "-cert-file", path.Join(*resourceDir, rsaCertificateFile), - "-key-file", path.Join(*resourceDir, rsaKeyFile), - }, - shouldFail: true, - expectedError: ":DECODE_ERROR:", + shimCertificate: &rsaCertificate, + shouldFail: true, + expectedError: ":DECODE_ERROR:", }) testCases = append(testCases, testCase{ @@ -14613,10 +14469,7 @@ func addTLS13HandshakeTests() { SendCustomCertificateRequest: 0x1212, }, }, - flags: []string{ - "-cert-file", path.Join(*resourceDir, rsaCertificateFile), - "-key-file", path.Join(*resourceDir, rsaKeyFile), - }, + shimCertificate: &rsaCertificate, }) testCases = append(testCases, testCase{ @@ -14629,12 +14482,9 @@ func addTLS13HandshakeTests() { OmitCertificateRequestAlgorithms: true, }, }, - flags: []string{ - "-cert-file", path.Join(*resourceDir, rsaCertificateFile), - "-key-file", path.Join(*resourceDir, rsaKeyFile), - }, - shouldFail: true, - expectedError: ":DECODE_ERROR:", + shimCertificate: &rsaCertificate, + shouldFail: true, + expectedError: ":DECODE_ERROR:", }) testCases = append(testCases, testCase{ @@ -14705,12 +14555,12 @@ func addTLS13HandshakeTests() { testType: clientTest, name: "EarlyData-RejectTicket-Client-TLS13", config: Config{ - MaxVersion: VersionTLS13, - Certificates: []Certificate{rsaCertificate}, + MaxVersion: VersionTLS13, + Chains: []CertificateChain{rsaCertificate}, }, resumeConfig: &Config{ MaxVersion: VersionTLS13, - Certificates: []Certificate{ecdsaP256Certificate}, + Chains: []CertificateChain{ecdsaP256Certificate}, SessionTicketsDisabled: true, }, resumeSession: true, @@ -14721,9 +14571,9 @@ func addTLS13HandshakeTests() { "-on-retry-expect-early-data-reason", "session_not_resumed", // Test the peer certificate is reported correctly in each of the // three logical connections. - "-on-initial-expect-peer-cert-file", path.Join(*resourceDir, rsaCertificateFile), - "-on-resume-expect-peer-cert-file", path.Join(*resourceDir, rsaCertificateFile), - "-on-retry-expect-peer-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile), + "-on-initial-expect-peer-cert-file", rsaCertificate.ChainPath, + "-on-resume-expect-peer-cert-file", rsaCertificate.ChainPath, + "-on-retry-expect-peer-cert-file", ecdsaP256Certificate.ChainPath, // Session tickets are disabled, so the runner will not send a ticket. "-on-retry-expect-no-session", }, @@ -14800,12 +14650,12 @@ func addTLS13HandshakeTests() { testType: clientTest, name: "EarlyData-HRR-RejectTicket-Client-TLS13", config: Config{ - MaxVersion: VersionTLS13, - Certificates: []Certificate{rsaCertificate}, + MaxVersion: VersionTLS13, + Chains: []CertificateChain{rsaCertificate}, }, resumeConfig: &Config{ MaxVersion: VersionTLS13, - Certificates: []Certificate{ecdsaP256Certificate}, + Chains: []CertificateChain{ecdsaP256Certificate}, SessionTicketsDisabled: true, Bugs: ProtocolBugs{ SendHelloRetryRequestCookie: []byte{1, 2, 3, 4}, @@ -14821,9 +14671,9 @@ func addTLS13HandshakeTests() { "-on-retry-expect-early-data-reason", "hello_retry_request", // Test the peer certificate is reported correctly in each of the // three logical connections. - "-on-initial-expect-peer-cert-file", path.Join(*resourceDir, rsaCertificateFile), - "-on-resume-expect-peer-cert-file", path.Join(*resourceDir, rsaCertificateFile), - "-on-retry-expect-peer-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile), + "-on-initial-expect-peer-cert-file", rsaCertificate.ChainPath, + "-on-resume-expect-peer-cert-file", rsaCertificate.ChainPath, + "-on-retry-expect-peer-cert-file", ecdsaP256Certificate.ChainPath, // Session tickets are disabled, so the runner will not send a ticket. "-on-retry-expect-no-session", }, @@ -15255,7 +15105,7 @@ func addTLS13HandshakeTests() { expectedError: ":UNEXPECTED_EXTENSION_ON_EARLY_DATA:", expectedLocalError: "remote error: illegal parameter", flags: []string{ - "-send-channel-id", path.Join(*resourceDir, channelIDKeyFile), + "-send-channel-id", channelIDKeyPath, }, }) @@ -15278,7 +15128,7 @@ func addTLS13HandshakeTests() { channelID: true, }, flags: []string{ - "-send-channel-id", path.Join(*resourceDir, channelIDKeyFile), + "-send-channel-id", channelIDKeyPath, // The client never learns the reason was Channel ID. "-on-retry-expect-early-data-reason", "peer_declined", }, @@ -15295,7 +15145,7 @@ func addTLS13HandshakeTests() { resumeSession: true, earlyData: true, flags: []string{ - "-send-channel-id", path.Join(*resourceDir, channelIDKeyFile), + "-send-channel-id", channelIDKeyPath, }, }) @@ -15306,7 +15156,7 @@ func addTLS13HandshakeTests() { name: "EarlyDataChannelID-OfferBoth-Server-TLS13", config: Config{ MaxVersion: VersionTLS13, - ChannelID: channelIDKey, + ChannelID: &channelIDKey, }, resumeSession: true, earlyData: true, @@ -15455,19 +15305,18 @@ func addTLS13HandshakeTests() { testType: serverTest, name: "ServerSkipCertificateVerify-TLS13", config: Config{ - MinVersion: VersionTLS13, - MaxVersion: VersionTLS13, - Certificates: []Certificate{rsaChainCertificate}, + MinVersion: VersionTLS13, + MaxVersion: VersionTLS13, + Chains: []CertificateChain{rsaChainCertificate}, Bugs: ProtocolBugs{ SkipCertificateVerify: true, }, }, expectations: connectionExpectations{ - peerCertificate: &rsaChainCertificate, + peerCertificate: &rsaCertificate, }, + shimCertificate: &rsaCertificate, flags: []string{ - "-cert-file", path.Join(*resourceDir, rsaChainCertificateFile), - "-key-file", path.Join(*resourceDir, rsaChainKeyFile), "-require-any-client-certificate", }, shouldFail: true, @@ -15478,20 +15327,17 @@ func addTLS13HandshakeTests() { testType: clientTest, name: "ClientSkipCertificateVerify-TLS13", config: Config{ - MinVersion: VersionTLS13, - MaxVersion: VersionTLS13, - Certificates: []Certificate{rsaChainCertificate}, + MinVersion: VersionTLS13, + MaxVersion: VersionTLS13, + Chains: []CertificateChain{rsaChainCertificate}, Bugs: ProtocolBugs{ SkipCertificateVerify: true, }, }, expectations: connectionExpectations{ - peerCertificate: &rsaChainCertificate, - }, - flags: []string{ - "-cert-file", path.Join(*resourceDir, rsaChainCertificateFile), - "-key-file", path.Join(*resourceDir, rsaChainKeyFile), + peerCertificate: &rsaCertificate, }, + shimCertificate: &rsaCertificate, shouldFail: true, expectedError: ":UNEXPECTED_MESSAGE:", expectedLocalError: "remote error: unexpected message", @@ -15995,18 +15841,17 @@ func addCertificateTests() { testType: clientTest, name: "SendReceiveIntermediate-Client-" + ver.name, config: Config{ - MinVersion: ver.version, - MaxVersion: ver.version, - Certificates: []Certificate{rsaChainCertificate}, - ClientAuth: RequireAnyClientCert, + MinVersion: ver.version, + MaxVersion: ver.version, + Chains: []CertificateChain{rsaChainCertificate}, + ClientAuth: RequireAnyClientCert, }, expectations: connectionExpectations{ peerCertificate: &rsaChainCertificate, }, + shimCertificate: &rsaChainCertificate, flags: []string{ - "-cert-file", path.Join(*resourceDir, rsaChainCertificateFile), - "-key-file", path.Join(*resourceDir, rsaChainKeyFile), - "-expect-peer-cert-file", path.Join(*resourceDir, rsaChainCertificateFile), + "-expect-peer-cert-file", rsaChainCertificate.ChainPath, }, }) @@ -16014,18 +15859,17 @@ func addCertificateTests() { testType: serverTest, name: "SendReceiveIntermediate-Server-" + ver.name, config: Config{ - MinVersion: ver.version, - MaxVersion: ver.version, - Certificates: []Certificate{rsaChainCertificate}, + MinVersion: ver.version, + MaxVersion: ver.version, + Chains: []CertificateChain{rsaChainCertificate}, }, expectations: connectionExpectations{ peerCertificate: &rsaChainCertificate, }, + shimCertificate: &rsaChainCertificate, flags: []string{ - "-cert-file", path.Join(*resourceDir, rsaChainCertificateFile), - "-key-file", path.Join(*resourceDir, rsaChainKeyFile), "-require-any-client-certificate", - "-expect-peer-cert-file", path.Join(*resourceDir, rsaChainCertificateFile), + "-expect-peer-cert-file", rsaChainCertificate.ChainPath, }, }) @@ -16034,9 +15878,9 @@ func addCertificateTests() { testType: clientTest, name: "GarbageCertificate-Client-" + ver.name, config: Config{ - MinVersion: ver.version, - MaxVersion: ver.version, - Certificates: []Certificate{garbageCertificate}, + MinVersion: ver.version, + MaxVersion: ver.version, + Chains: []CertificateChain{garbageCertificate}, }, shouldFail: true, expectedError: ":CANNOT_PARSE_LEAF_CERT:", @@ -16047,9 +15891,9 @@ func addCertificateTests() { testType: serverTest, name: "GarbageCertificate-Server-" + ver.name, config: Config{ - MinVersion: ver.version, - MaxVersion: ver.version, - Certificates: []Certificate{garbageCertificate}, + MinVersion: ver.version, + MaxVersion: ver.version, + Chains: []CertificateChain{garbageCertificate}, }, flags: []string{"-require-any-client-certificate"}, shouldFail: true, @@ -16084,9 +15928,9 @@ func addRetainOnlySHA256ClientCertTests() { testType: serverTest, name: "RetainOnlySHA256-Cert-" + ver.name, config: Config{ - MinVersion: ver.version, - MaxVersion: ver.version, - Certificates: []Certificate{rsaCertificate}, + MinVersion: ver.version, + MaxVersion: ver.version, + Chains: []CertificateChain{rsaCertificate}, }, flags: []string{ "-verify-peer", @@ -16105,9 +15949,9 @@ func addRetainOnlySHA256ClientCertTests() { testType: serverTest, name: "RetainOnlySHA256-OnOff-" + ver.name, config: Config{ - MinVersion: ver.version, - MaxVersion: ver.version, - Certificates: []Certificate{rsaCertificate}, + MinVersion: ver.version, + MaxVersion: ver.version, + Chains: []CertificateChain{rsaCertificate}, }, flags: []string{ "-verify-peer", @@ -16125,9 +15969,9 @@ func addRetainOnlySHA256ClientCertTests() { testType: serverTest, name: "RetainOnlySHA256-OffOn-" + ver.name, config: Config{ - MinVersion: ver.version, - MaxVersion: ver.version, - Certificates: []Certificate{rsaCertificate}, + MinVersion: ver.version, + MaxVersion: ver.version, + Chains: []CertificateChain{rsaCertificate}, }, flags: []string{ "-verify-peer", @@ -16141,19 +15985,13 @@ func addRetainOnlySHA256ClientCertTests() { } func addECDSAKeyUsageTests() { - p256 := elliptic.P256() - priv, err := ecdsa.GenerateKey(p256, rand.Reader) - if err != nil { - panic(err) - } - serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) if err != nil { panic(err) } - template := x509.Certificate{ + template := &x509.Certificate{ SerialNumber: serialNumber, Subject: pkix.Name{ Organization: []string{"Acme Co"}, @@ -16168,15 +16006,7 @@ func addECDSAKeyUsageTests() { BasicConstraintsValid: true, } - derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv) - if err != nil { - panic(err) - } - - cert := Certificate{ - Certificate: [][]byte{derBytes}, - PrivateKey: priv, - } + cert := generateSingleCertChain(template, &ecdsaP256Key, nil, nil) for _, ver := range tlsVersions { if ver.version < VersionTLS12 { @@ -16187,9 +16017,9 @@ func addECDSAKeyUsageTests() { testType: clientTest, name: "ECDSAKeyUsage-Client-" + ver.name, config: Config{ - MinVersion: ver.version, - MaxVersion: ver.version, - Certificates: []Certificate{cert}, + MinVersion: ver.version, + MaxVersion: ver.version, + Chains: []CertificateChain{cert}, }, shouldFail: true, expectedError: ":KEY_USAGE_BIT_INCORRECT:", @@ -16199,9 +16029,9 @@ func addECDSAKeyUsageTests() { testType: serverTest, name: "ECDSAKeyUsage-Server-" + ver.name, config: Config{ - MinVersion: ver.version, - MaxVersion: ver.version, - Certificates: []Certificate{cert}, + MinVersion: ver.version, + MaxVersion: ver.version, + Chains: []CertificateChain{cert}, }, flags: []string{"-require-any-client-certificate"}, shouldFail: true, @@ -16243,25 +16073,9 @@ func addRSAKeyUsageTests() { BasicConstraintsValid: true, } - dsDerBytes, err := x509.CreateCertificate(rand.Reader, &dsTemplate, &dsTemplate, &priv.PublicKey, priv) - if err != nil { - panic(err) - } + dsCert := generateSingleCertChain(&dsTemplate, priv, nil, nil) - encDerBytes, err := x509.CreateCertificate(rand.Reader, &encTemplate, &encTemplate, &priv.PublicKey, priv) - if err != nil { - panic(err) - } - - dsCert := Certificate{ - Certificate: [][]byte{dsDerBytes}, - PrivateKey: priv, - } - - encCert := Certificate{ - Certificate: [][]byte{encDerBytes}, - PrivateKey: priv, - } + encCert := generateSingleCertChain(&encTemplate, priv, nil, nil) dsSuites := []uint16{ TLS_AES_128_GCM_SHA256, @@ -16280,7 +16094,7 @@ func addRSAKeyUsageTests() { config: Config{ MinVersion: ver.version, MaxVersion: ver.version, - Certificates: []Certificate{encCert}, + Chains: []CertificateChain{encCert}, CipherSuites: dsSuites, }, shouldFail: true, @@ -16296,7 +16110,7 @@ func addRSAKeyUsageTests() { config: Config{ MinVersion: ver.version, MaxVersion: ver.version, - Certificates: []Certificate{dsCert}, + Chains: []CertificateChain{dsCert}, CipherSuites: dsSuites, }, flags: []string{ @@ -16312,7 +16126,7 @@ func addRSAKeyUsageTests() { config: Config{ MinVersion: ver.version, MaxVersion: ver.version, - Certificates: []Certificate{encCert}, + Chains: []CertificateChain{encCert}, CipherSuites: encSuites, }, flags: []string{ @@ -16326,7 +16140,7 @@ func addRSAKeyUsageTests() { config: Config{ MinVersion: ver.version, MaxVersion: ver.version, - Certificates: []Certificate{dsCert}, + Chains: []CertificateChain{dsCert}, CipherSuites: encSuites, }, shouldFail: true, @@ -16343,7 +16157,7 @@ func addRSAKeyUsageTests() { config: Config{ MinVersion: ver.version, MaxVersion: ver.version, - Certificates: []Certificate{dsCert}, + Chains: []CertificateChain{dsCert}, CipherSuites: encSuites, }, flags: []string{"-expect-key-usage-invalid"}, @@ -16355,7 +16169,7 @@ func addRSAKeyUsageTests() { config: Config{ MinVersion: ver.version, MaxVersion: ver.version, - Certificates: []Certificate{encCert}, + Chains: []CertificateChain{encCert}, CipherSuites: dsSuites, }, flags: []string{"-expect-key-usage-invalid"}, @@ -16370,7 +16184,7 @@ func addRSAKeyUsageTests() { config: Config{ MinVersion: ver.version, MaxVersion: ver.version, - Certificates: []Certificate{encCert}, + Chains: []CertificateChain{encCert}, CipherSuites: dsSuites, }, shouldFail: true, @@ -16383,9 +16197,9 @@ func addRSAKeyUsageTests() { testType: serverTest, name: "RSAKeyUsage-Server-WantSignature-GotEncipherment-" + ver.name, config: Config{ - MinVersion: ver.version, - MaxVersion: ver.version, - Certificates: []Certificate{encCert}, + MinVersion: ver.version, + MaxVersion: ver.version, + Chains: []CertificateChain{encCert}, }, shouldFail: true, expectedError: ":KEY_USAGE_BIT_INCORRECT:", @@ -16396,9 +16210,9 @@ func addRSAKeyUsageTests() { testType: serverTest, name: "RSAKeyUsage-Server-WantSignature-GotSignature-" + ver.name, config: Config{ - MinVersion: ver.version, - MaxVersion: ver.version, - Certificates: []Certificate{dsCert}, + MinVersion: ver.version, + MaxVersion: ver.version, + Chains: []CertificateChain{dsCert}, }, flags: []string{"-require-any-client-certificate"}, }) @@ -17062,26 +16876,9 @@ func addJDK11WorkaroundTests() { } func addDelegatedCredentialTests() { - certPath := path.Join(*resourceDir, rsaCertificateFile) - pemBytes, err := os.ReadFile(certPath) - if err != nil { - panic(err) - } - - block, _ := pem.Decode(pemBytes) - if block == nil { - panic(fmt.Sprintf("no PEM block found in %q", certPath)) - } - parentDER := block.Bytes - - rsaPriv, _, err := loadRSAPrivateKey(rsaKeyFile) - if err != nil { - panic(err) - } - ecdsaDC, ecdsaPKCS8, err := createDelegatedCredential(delegatedCredentialConfig{ algo: signatureRSAPSSWithSHA256, - }, parentDER, rsaPriv) + }, rsaCertificate.Leaf.Raw, rsaCertificate.PrivateKey) if err != nil { panic(err) } @@ -17137,32 +16934,42 @@ func addDelegatedCredentialTests() { }, }) - // This flag value has mismatched public and private keys which should cause a - // configuration error in the shim. - _, badTLSVersionPKCS8, err := createDelegatedCredential(delegatedCredentialConfig{ - algo: signatureRSAPSSWithSHA256, - tlsVersion: 0x1234, - }, parentDER, rsaPriv) + // Generate another delegated credential, so we can get the keys out of sync. + _, ecdsaPKCS8Wrong, err := createDelegatedCredential(delegatedCredentialConfig{ + algo: signatureRSAPSSWithSHA256, + }, rsaCertificate.Leaf.Raw, rsaCertificate.PrivateKey) if err != nil { panic(err) } - mismatchFlagValue := fmt.Sprintf("%x,%x", ecdsaDC, badTLSVersionPKCS8) + mismatchFlagValue := fmt.Sprintf("%x,%x", ecdsaDC, ecdsaPKCS8Wrong) testCases = append(testCases, testCase{ testType: serverTest, name: "DelegatedCredentials-KeyMismatch", - config: Config{ - MinVersion: VersionTLS13, - MaxVersion: VersionTLS13, - Bugs: ProtocolBugs{ - FailIfDelegatedCredentials: true, - }, - }, flags: []string{ "-delegated-credential", mismatchFlagValue, }, shouldFail: true, expectedError: ":KEY_VALUES_MISMATCH:", }) + + // RSA delegated credentials should be rejected at configuration time. + rsaDC, rsaPKCS8, err := createDelegatedCredential(delegatedCredentialConfig{ + algo: signatureRSAPSSWithSHA256, + dcAlgo: signatureRSAPSSWithSHA256, + }, rsaCertificate.Leaf.Raw, rsaCertificate.PrivateKey) + if err != nil { + panic(err) + } + rsaFlagValue := fmt.Sprintf("%x,%x", rsaDC, rsaPKCS8) + testCases = append(testCases, testCase{ + testType: serverTest, + name: "DelegatedCredentials-NoRSA", + flags: []string{ + "-delegated-credential", rsaFlagValue, + }, + shouldFail: true, + expectedError: ":INVALID_SIGNATURE_ALGORITHM:", + }) } type echCipher struct { @@ -17950,7 +17757,7 @@ write hs 4 protocol: protocol, name: prefix + "ECH-Server-ClientAuth", config: Config{ - Certificates: []Certificate{rsaCertificate}, + Chains: []CertificateChain{rsaCertificate}, ClientECHConfig: echConfig.ECHConfig, }, flags: []string{ @@ -17969,7 +17776,7 @@ write hs 4 protocol: protocol, name: prefix + "ECH-Server-Decline-ClientAuth", config: Config{ - Certificates: []Certificate{rsaCertificate}, + Chains: []CertificateChain{rsaCertificate}, ClientECHConfig: echConfig.ECHConfig, Bugs: ProtocolBugs{ ExpectECHRetryConfigs: CreateECHConfigList(echConfig1.ECHConfig.Raw), @@ -19091,9 +18898,8 @@ write hs 4 ServerECHConfigs: []ServerECHConfig{echConfig}, ClientAuth: RequireAnyClientCert, }, + shimCertificate: &rsaCertificate, flags: append([]string{ - "-cert-file", path.Join(*resourceDir, rsaCertificateFile), - "-key-file", path.Join(*resourceDir, rsaKeyFile), "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), "-expect-ech-accept", }, flags...), @@ -19111,9 +18917,8 @@ write hs 4 MaxVersion: VersionTLS13, ClientAuth: RequireAnyClientCert, }, + shimCertificate: &rsaCertificate, flags: append([]string{ - "-cert-file", path.Join(*resourceDir, rsaCertificateFile), - "-key-file", path.Join(*resourceDir, rsaKeyFile), "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), }, flags...), shouldFail: true, @@ -19129,9 +18934,8 @@ write hs 4 MaxVersion: VersionTLS12, ClientAuth: RequireAnyClientCert, }, + shimCertificate: &rsaCertificate, flags: append([]string{ - "-cert-file", path.Join(*resourceDir, rsaCertificateFile), - "-key-file", path.Join(*resourceDir, rsaKeyFile), "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), }, flags...), shouldFail: true, @@ -19150,7 +18954,7 @@ write hs 4 RequestChannelID: true, }, flags: []string{ - "-send-channel-id", path.Join(*resourceDir, channelIDKeyFile), + "-send-channel-id", channelIDKeyPath, "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), "-expect-ech-accept", }, @@ -19174,7 +18978,7 @@ write hs 4 }, }, flags: []string{ - "-send-channel-id", path.Join(*resourceDir, channelIDKeyFile), + "-send-channel-id", channelIDKeyPath, "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), }, shouldFail: true, @@ -19194,7 +18998,7 @@ write hs 4 }, }, flags: []string{ - "-send-channel-id", path.Join(*resourceDir, channelIDKeyFile), + "-send-channel-id", channelIDKeyPath, "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), }, shouldFail: true, @@ -19550,10 +19354,9 @@ func addHintMismatchTests() { signatureRSAPSSWithSHA384, }, }, + shimCertificate: &rsaCertificate, flags: []string{ "-allow-hint-mismatch", - "-cert-file", path.Join(*resourceDir, rsaCertificateFile), - "-key-file", path.Join(*resourceDir, rsaKeyFile), "-on-shim-signing-prefs", strconv.Itoa(int(signatureRSAPSSWithSHA256)), "-on-handshaker-signing-prefs", strconv.Itoa(int(signatureRSAPSSWithSHA384)), }, @@ -19575,10 +19378,9 @@ func addHintMismatchTests() { signatureRSAPSSWithSHA384, }, }, + shimCertificate: &rsaCertificate, flags: []string{ "-allow-hint-mismatch", - "-cert-file", path.Join(*resourceDir, rsaCertificateFile), - "-key-file", path.Join(*resourceDir, rsaKeyFile), "-on-shim-signing-prefs", strconv.Itoa(int(signatureRSAPSSWithSHA256)), "-on-handshaker-signing-prefs", strconv.Itoa(int(signatureRSAPSSWithSHA384)), }, @@ -19664,9 +19466,9 @@ func addHintMismatchTests() { protocol: protocol, skipSplitHandshake: true, config: Config{ - MinVersion: VersionTLS13, - MaxVersion: VersionTLS13, - Certificates: []Certificate{rsaCertificate}, + MinVersion: VersionTLS13, + MaxVersion: VersionTLS13, + Chains: []CertificateChain{rsaCertificate}, }, flags: []string{ "-allow-hint-mismatch", @@ -19860,28 +19662,28 @@ var testMultipleCertSlotsAlgorithms = []struct { name string cipher uint16 id signatureAlgorithm - cert testCert + cert *CertificateChain // If non-zero, the curve that must be supported in TLS 1.2 for cert to be // accepted. curve CurveID }{ - {"RSA_PKCS1_SHA1", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, signatureRSAPKCS1WithSHA1, testCertRSA, 0}, - {"RSA_PKCS1_SHA256", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, signatureRSAPKCS1WithSHA256, testCertRSA, 0}, - {"RSA_PKCS1_SHA384", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, signatureRSAPKCS1WithSHA384, testCertRSA, 0}, - {"RSA_PKCS1_SHA512", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, signatureRSAPKCS1WithSHA512, testCertRSA, 0}, - {"ECDSA_SHA1", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, signatureECDSAWithSHA1, testCertECDSAP256, CurveP256}, + {"RSA_PKCS1_SHA1", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, signatureRSAPKCS1WithSHA1, &rsaCertificate, 0}, + {"RSA_PKCS1_SHA256", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, signatureRSAPKCS1WithSHA256, &rsaCertificate, 0}, + {"RSA_PKCS1_SHA384", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, signatureRSAPKCS1WithSHA384, &rsaCertificate, 0}, + {"RSA_PKCS1_SHA512", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, signatureRSAPKCS1WithSHA512, &rsaCertificate, 0}, + {"ECDSA_SHA1", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, signatureECDSAWithSHA1, &ecdsaP256Certificate, CurveP256}, // The “P256” in the following line is not a mistake. In TLS 1.2 the // hash function doesn't have to match the curve and so the same // signature algorithm works with P-224. - {"ECDSA_P224_SHA256", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, signatureECDSAWithP256AndSHA256, testCertECDSAP224, CurveP224}, - {"ECDSA_P256_SHA256", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, signatureECDSAWithP256AndSHA256, testCertECDSAP256, CurveP256}, - {"RSA_PSS_SHA256", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, signatureRSAPSSWithSHA256, testCertRSA, 0}, - {"RSA_PSS_SHA384", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, signatureRSAPSSWithSHA384, testCertRSA, 0}, - {"RSA_PSS_SHA512", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, signatureRSAPSSWithSHA512, testCertRSA, 0}, - {"Ed25519", TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, signatureEd25519, testCertEd25519, 0}, + {"ECDSA_P224_SHA256", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, signatureECDSAWithP256AndSHA256, &ecdsaP224Certificate, CurveP224}, + {"ECDSA_P256_SHA256", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, signatureECDSAWithP256AndSHA256, &ecdsaP256Certificate, CurveP256}, + {"RSA_PSS_SHA256", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, signatureRSAPSSWithSHA256, &rsaCertificate, 0}, + {"RSA_PSS_SHA384", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, signatureRSAPSSWithSHA384, &rsaCertificate, 0}, + {"RSA_PSS_SHA512", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, signatureRSAPSSWithSHA512, &rsaCertificate, 0}, + {"Ed25519", TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, signatureEd25519, &ed25519Certificate, 0}, // Tests for key types prior to TLS 1.2. - {"RSA", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0, testCertRSA, 0}, - {"ECDSA", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 0, testCertECDSAP256, CurveP256}, + {"RSA", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0, &rsaCertificate, 0}, + {"ECDSA", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 0, &ecdsaP256Certificate, CurveP256}, } func addMultipleCertSlotTests() { @@ -19893,13 +19695,13 @@ func addMultipleCertSlotTests() { } multipleCertsFlag := "-multiple-certs-slot" rsaCertSlot := []string{ - multipleCertsFlag, path.Join(*resourceDir, getShimCertificate(testCertRSA)) + "," + path.Join(*resourceDir, getShimKey(testCertRSA)), + multipleCertsFlag, rsaCertificate.ChainPath + "," + rsaCertificate.KeyPath, } ecdsaCertSlot := []string{ - multipleCertsFlag, path.Join(*resourceDir, getShimCertificate(testCertECDSAP256)) + "," + path.Join(*resourceDir, getShimKey(testCertECDSAP256)), + multipleCertsFlag, ecdsaP256Certificate.ChainPath + "," + ecdsaP256Certificate.KeyPath, } ed25519CertSlot := []string{ - multipleCertsFlag, path.Join(*resourceDir, getShimCertificate(testCertEd25519)) + "," + path.Join(*resourceDir, getShimKey(testCertEd25519)), + multipleCertsFlag, ed25519Certificate.ChainPath + "," + ed25519Certificate.KeyPath, } certificateSlotFlags := append([]string{}, rsaCertSlot...) certificateSlotFlags = append(certificateSlotFlags, ecdsaCertSlot...) @@ -19927,7 +19729,7 @@ func addMultipleCertSlotTests() { } // SHA-224 has been removed from TLS 1.3 and, in 1.3, // the curve has to match the hash size. - if ver.version >= VersionTLS13 && alg.cert == testCertECDSAP224 { + if ver.version >= VersionTLS13 && alg.cert == &ecdsaP224Certificate { shouldFail = true } @@ -19985,7 +19787,7 @@ func addMultipleCertSlotTests() { MaxVersion: ver.version, VerifySignatureAlgorithms: []signatureAlgorithm{alg.id}, ClientAuth: RequireAnyClientCert, - Certificates: []Certificate{rsaCertificate, ecdsaP256Certificate, ed25519Certificate}, + Chains: []CertificateChain{rsaCertificate, ecdsaP256Certificate, ed25519Certificate}, }, flags: func() []string { flags := append([]string{}, certificateSlotFlags...) @@ -20360,7 +20162,13 @@ var sslTransferHelper *ssl_transfer.TestHelper func main() { flag.Parse() - *resourceDir = path.Clean(*resourceDir) + var err error + if tmpDir, err = os.MkdirTemp("", "testing-certs"); err != nil { + fmt.Fprintf(os.Stderr, "failed to make temporary directory: %s", err) + os.Exit(1) + } + defer os.RemoveAll(tmpDir) + initKeys() initCertificates() if len(*shimConfigFile) != 0 { diff --git a/ssl/test/runner/tls.go b/ssl/test/runner/tls.go index 6e57d18197..bd94275ce2 100644 --- a/ssl/test/runner/tls.go +++ b/ssl/test/runner/tls.go @@ -73,7 +73,7 @@ func NewListener(inner net.Listener, config *Config) net.Listener { // The configuration config must be non-nil and must have // at least one certificate. func Listen(network, laddr string, config *Config) (net.Listener, error) { - if config == nil || len(config.Certificates) == 0 { + if config == nil || len(config.Chains) == 0 { return nil, errors.New("tls.Listen: no certificates in configuration") } l, err := net.Listen(network, laddr) @@ -173,7 +173,7 @@ func Dial(network, addr string, config *Config) (*Conn, error) { // LoadX509KeyPair reads and parses a public/private key pair from a pair of // files. The files must contain PEM encoded data. -func LoadX509KeyPair(certFile, keyFile string) (cert Certificate, err error) { +func LoadX509KeyPair(certFile, keyFile string) (cert CertificateChain, err error) { certPEMBlock, err := os.ReadFile(certFile) if err != nil { return @@ -187,7 +187,7 @@ func LoadX509KeyPair(certFile, keyFile string) (cert Certificate, err error) { // X509KeyPair parses a public/private key pair from a pair of // PEM encoded data. -func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (cert Certificate, err error) { +func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (cert CertificateChain, err error) { var certDERBlock *pem.Block for { certDERBlock, certPEMBlock = pem.Decode(certPEMBlock) diff --git a/ssl/test/test_config.cc b/ssl/test/test_config.cc index 8e3a0a2520..c73be95297 100644 --- a/ssl/test/test_config.cc +++ b/ssl/test/test_config.cc @@ -218,6 +218,7 @@ std::vector SortedFlags() { IntVectorFlag("-curves", &TestConfig::curves), StringFlag("-key-file", &TestConfig::key_file), StringFlag("-cert-file", &TestConfig::cert_file), + StringFlag("-trust-cert", &TestConfig::trust_cert), StringFlag("-expect-server-name", &TestConfig::expect_server_name), BoolFlag("-enable-ech-grease", &TestConfig::enable_ech_grease), Base64VectorFlag("-ech-server-config", &TestConfig::ech_server_configs), diff --git a/ssl/test/test_config.h b/ssl/test/test_config.h index 05f73b3ed7..fbf1c60c8d 100644 --- a/ssl/test/test_config.h +++ b/ssl/test/test_config.h @@ -40,6 +40,7 @@ struct TestConfig { std::vector curves; std::string key_file; std::string cert_file; + std::string trust_cert; std::string expect_server_name; bool enable_ech_grease = false; std::vector ech_server_configs; diff --git a/util/run_android_tests.go b/util/run_android_tests.go index 752b8ab4b4..0f02776fe7 100644 --- a/util/run_android_tests.go +++ b/util/run_android_tests.go @@ -338,28 +338,6 @@ func main() { if enableSSLTests() { binaries = append(binaries, "ssl/test/bssl_shim") - files = append(files, - "BUILDING.md", - "ssl/test/runner/cert.pem", - "ssl/test/runner/channel_id_key.pem", - "ssl/test/runner/ecdsa_p224_cert.pem", - "ssl/test/runner/ecdsa_p224_key.pem", - "ssl/test/runner/ecdsa_p256_cert.pem", - "ssl/test/runner/ecdsa_p256_key.pem", - "ssl/test/runner/ecdsa_p384_cert.pem", - "ssl/test/runner/ecdsa_p384_key.pem", - "ssl/test/runner/ecdsa_p521_cert.pem", - "ssl/test/runner/ecdsa_p521_key.pem", - "ssl/test/runner/ed25519_cert.pem", - "ssl/test/runner/ed25519_key.pem", - "ssl/test/runner/key.pem", - "ssl/test/runner/rsa_1024_cert.pem", - "ssl/test/runner/rsa_1024_key.pem", - "ssl/test/runner/rsa_chain_cert.pem", - "ssl/test/runner/rsa_chain_key.pem", - "util/all_tests.json", - ) - fmt.Printf("Building runner...\n") if err := goTool("test", "-c", "-o", filepath.Join(tmpDir, "ssl/test/runner/runner"), "./ssl/test/runner/"); err != nil { fmt.Printf("Error building runner: %s\n", err)