summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Benjamin <davidben@chromium.org>2014-10-27 01:06:24 -0400
committerAdam Langley <agl@google.com>2014-10-29 20:32:21 +0000
commit48cae085630e85095740e23ccdffc55f29a8a60a (patch)
tree87ffda5a5973c06f2dbcfdf50a370db2342b5c95
parentb06711ca34a0f11d345bf35e07e1a2d0c068ab9e (diff)
downloadsrc-48cae085630e85095740e23ccdffc55f29a8a60a.tar.gz
Add tests for PSK cipher suites.
Only the three plain PSK suites for now. ECDHE_PSK_WITH_AES_128_GCM_SHA256 will be in a follow-up. Change-Id: Iafc116a5b2798c61d90c139b461cf98897ae23b3 Reviewed-on: https://boringssl-review.googlesource.com/2051 Reviewed-by: Adam Langley <agl@google.com>
-rw-r--r--ssl/test/bssl_shim.cc53
-rw-r--r--ssl/test/runner/cipher_suites.go13
-rw-r--r--ssl/test/runner/common.go15
-rw-r--r--ssl/test/runner/handshake_client.go97
-rw-r--r--ssl/test/runner/handshake_server.go16
-rw-r--r--ssl/test/runner/key_agreement.go87
-rw-r--r--ssl/test/runner/runner.go89
-rw-r--r--ssl/test/test_config.cc2
-rw-r--r--ssl/test/test_config.h2
9 files changed, 301 insertions, 73 deletions
diff --git a/ssl/test/bssl_shim.cc b/ssl/test/bssl_shim.cc
index d04c3c0..1cf81a7 100644
--- a/ssl/test/bssl_shim.cc
+++ b/ssl/test/bssl_shim.cc
@@ -25,6 +25,7 @@
#include <sys/types.h>
#include <openssl/bio.h>
+#include <openssl/buf.h>
#include <openssl/bytestring.h>
#include <openssl/ssl.h>
@@ -180,6 +181,48 @@ static int cookie_verify_callback(SSL *ssl, const uint8_t *cookie, size_t cookie
return 1;
}
+static unsigned psk_client_callback(SSL *ssl, const char *hint,
+ char *out_identity,
+ unsigned max_identity_len,
+ uint8_t *out_psk, unsigned max_psk_len) {
+ const TestConfig *config = GetConfigPtr(ssl);
+
+ if (strcmp(hint ? hint : "", config->psk_identity.c_str()) != 0) {
+ fprintf(stderr, "Server PSK hint did not match.\n");
+ return 0;
+ }
+
+ // Account for the trailing '\0' for the identity.
+ if (config->psk_identity.size() >= max_identity_len ||
+ config->psk.size() > max_psk_len) {
+ fprintf(stderr, "PSK buffers too small\n");
+ return 0;
+ }
+
+ BUF_strlcpy(out_identity, config->psk_identity.c_str(),
+ max_identity_len);
+ memcpy(out_psk, config->psk.data(), config->psk.size());
+ return config->psk.size();
+}
+
+static unsigned psk_server_callback(SSL *ssl, const char *identity,
+ uint8_t *out_psk, unsigned max_psk_len) {
+ const TestConfig *config = GetConfigPtr(ssl);
+
+ if (strcmp(identity, config->psk_identity.c_str()) != 0) {
+ fprintf(stderr, "Client PSK identity did not match.\n");
+ return 0;
+ }
+
+ if (config->psk.size() > max_psk_len) {
+ fprintf(stderr, "PSK buffers too small\n");
+ return 0;
+ }
+
+ memcpy(out_psk, config->psk.data(), config->psk.size());
+ return config->psk.size();
+}
+
static SSL_CTX *setup_ctx(const TestConfig *config) {
SSL_CTX *ssl_ctx = NULL;
DH *dh = NULL;
@@ -369,6 +412,16 @@ static int do_exchange(SSL_SESSION **out_session,
SSL_set_alpn_protos(ssl, (const uint8_t *)config->advertise_alpn.data(),
config->advertise_alpn.size());
}
+ if (!config->psk.empty()) {
+ SSL_set_psk_client_callback(ssl, psk_client_callback);
+ SSL_set_psk_server_callback(ssl, psk_server_callback);
+ }
+ if (!config->psk_identity.empty()) {
+ if (!SSL_use_psk_identity_hint(ssl, config->psk_identity.c_str())) {
+ BIO_print_errors_fp(stdout);
+ return 1;
+ }
+ }
BIO *bio = BIO_new_fd(fd, 1 /* take ownership */);
if (bio == NULL) {
diff --git a/ssl/test/runner/cipher_suites.go b/ssl/test/runner/cipher_suites.go
index 6cd0de9..a0e6b94 100644
--- a/ssl/test/runner/cipher_suites.go
+++ b/ssl/test/runner/cipher_suites.go
@@ -57,6 +57,9 @@ const (
// suiteNoDTLS indicates that the cipher suite cannot be used
// in DTLS.
suiteNoDTLS
+ // suitePSK indicates that the cipher suite authenticates with
+ // a pre-shared key rather than a server private key.
+ suitePSK
)
// A cipherSuite is a specific combination of key agreement, cipher and MAC
@@ -109,6 +112,9 @@ var cipherSuites = []*cipherSuite{
{TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, suiteECDHE, cipher3DES, macSHA1, nil},
{TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, dheRSAKA, 0, cipher3DES, macSHA1, nil},
{TLS_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, rsaKA, 0, cipher3DES, macSHA1, nil},
+ {TLS_PSK_WITH_RC4_128_SHA, 16, 20, 0, pskKA, suiteNoDTLS | suitePSK, cipherRC4, macSHA1, nil},
+ {TLS_PSK_WITH_AES_128_CBC_SHA, 16, 20, 16, pskKA, suitePSK, cipherAES, macSHA1, nil},
+ {TLS_PSK_WITH_AES_256_CBC_SHA, 32, 20, 16, pskKA, suitePSK, cipherAES, macSHA1, nil},
}
func cipherRC4(key, iv []byte, isRead bool) interface{} {
@@ -312,6 +318,10 @@ func dheRSAKA(version uint16) keyAgreement {
}
}
+func pskKA(version uint16) keyAgreement {
+ return &pskKeyAgreement{}
+}
+
// mutualCipherSuite returns a cipherSuite given a list of supported
// ciphersuites and the id requested by the peer.
func mutualCipherSuite(have []uint16, want uint16) *cipherSuite {
@@ -343,6 +353,9 @@ const (
TLS_RSA_WITH_AES_256_CBC_SHA256 uint16 = 0x003d
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x0067
TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 uint16 = 0x006b
+ TLS_PSK_WITH_RC4_128_SHA uint16 = 0x008a
+ TLS_PSK_WITH_AES_128_CBC_SHA uint16 = 0x008c
+ TLS_PSK_WITH_AES_256_CBC_SHA uint16 = 0x008d
TLS_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x009c
TLS_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x009d
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x009e
diff --git a/ssl/test/runner/common.go b/ssl/test/runner/common.go
index 935fd15..4aa21bb 100644
--- a/ssl/test/runner/common.go
+++ b/ssl/test/runner/common.go
@@ -325,6 +325,14 @@ type Config struct {
// returned in the ConnectionState.
RequestChannelID bool
+ // PreSharedKey, if not nil, is the pre-shared key to use with
+ // the PSK cipher suites.
+ PreSharedKey []byte
+
+ // PreSharedKeyIdentity, if not empty, is the identity to use
+ // with the PSK cipher suites.
+ PreSharedKeyIdentity string
+
// Bugs specifies optional misbehaviour to be used for testing other
// implementations.
Bugs ProtocolBugs
@@ -737,9 +745,10 @@ func defaultCipherSuites() []uint16 {
}
func initDefaultCipherSuites() {
- varDefaultCipherSuites = make([]uint16, len(cipherSuites))
- for i, suite := range cipherSuites {
- varDefaultCipherSuites[i] = suite.id
+ for _, suite := range cipherSuites {
+ if suite.flags&suitePSK == 0 {
+ varDefaultCipherSuites = append(varDefaultCipherSuites, suite.id)
+ }
}
}
diff --git a/ssl/test/runner/handshake_client.go b/ssl/test/runner/handshake_client.go
index 2f9fe12..11a1ed3 100644
--- a/ssl/test/runner/handshake_client.go
+++ b/ssl/test/runner/handshake_client.go
@@ -308,60 +308,65 @@ NextCipherSuite:
func (hs *clientHandshakeState) doFullHandshake() error {
c := hs.c
- msg, err := c.readHandshake()
- if err != nil {
- return err
- }
- certMsg, ok := msg.(*certificateMsg)
- if !ok || len(certMsg.certificates) == 0 {
- c.sendAlert(alertUnexpectedMessage)
- return unexpectedMessageError(certMsg, msg)
- }
- hs.writeServerHash(certMsg.marshal())
-
- certs := make([]*x509.Certificate, len(certMsg.certificates))
- for i, asn1Data := range certMsg.certificates {
- cert, err := x509.ParseCertificate(asn1Data)
+ var leaf *x509.Certificate
+ if hs.suite.flags&suitePSK == 0 {
+ msg, err := c.readHandshake()
if err != nil {
- c.sendAlert(alertBadCertificate)
- return errors.New("tls: failed to parse certificate from server: " + err.Error())
+ return err
}
- certs[i] = cert
- }
- if !c.config.InsecureSkipVerify {
- opts := x509.VerifyOptions{
- Roots: c.config.RootCAs,
- CurrentTime: c.config.time(),
- DNSName: c.config.ServerName,
- Intermediates: x509.NewCertPool(),
+ certMsg, ok := msg.(*certificateMsg)
+ if !ok || len(certMsg.certificates) == 0 {
+ c.sendAlert(alertUnexpectedMessage)
+ return unexpectedMessageError(certMsg, msg)
}
+ hs.writeServerHash(certMsg.marshal())
- for i, cert := range certs {
- if i == 0 {
- continue
+ certs := make([]*x509.Certificate, len(certMsg.certificates))
+ for i, asn1Data := range certMsg.certificates {
+ cert, err := x509.ParseCertificate(asn1Data)
+ if err != nil {
+ c.sendAlert(alertBadCertificate)
+ return errors.New("tls: failed to parse certificate from server: " + err.Error())
}
- opts.Intermediates.AddCert(cert)
+ certs[i] = cert
}
- c.verifiedChains, err = certs[0].Verify(opts)
- if err != nil {
- c.sendAlert(alertBadCertificate)
- return err
+ leaf = certs[0]
+
+ if !c.config.InsecureSkipVerify {
+ opts := x509.VerifyOptions{
+ Roots: c.config.RootCAs,
+ CurrentTime: c.config.time(),
+ DNSName: c.config.ServerName,
+ Intermediates: x509.NewCertPool(),
+ }
+
+ for i, cert := range certs {
+ if i == 0 {
+ continue
+ }
+ opts.Intermediates.AddCert(cert)
+ }
+ c.verifiedChains, err = leaf.Verify(opts)
+ if err != nil {
+ c.sendAlert(alertBadCertificate)
+ return err
+ }
}
- }
- switch certs[0].PublicKey.(type) {
- case *rsa.PublicKey, *ecdsa.PublicKey:
- break
- default:
- c.sendAlert(alertUnsupportedCertificate)
- return fmt.Errorf("tls: server's certificate contains an unsupported type of public key: %T", certs[0].PublicKey)
- }
+ switch leaf.PublicKey.(type) {
+ case *rsa.PublicKey, *ecdsa.PublicKey:
+ break
+ default:
+ c.sendAlert(alertUnsupportedCertificate)
+ return fmt.Errorf("tls: server's certificate contains an unsupported type of public key: %T", leaf.PublicKey)
+ }
- c.peerCertificates = certs
+ c.peerCertificates = certs
+ }
if hs.serverHello.ocspStapling {
- msg, err = c.readHandshake()
+ msg, err := c.readHandshake()
if err != nil {
return err
}
@@ -377,7 +382,7 @@ func (hs *clientHandshakeState) doFullHandshake() error {
}
}
- msg, err = c.readHandshake()
+ msg, err := c.readHandshake()
if err != nil {
return err
}
@@ -387,7 +392,7 @@ func (hs *clientHandshakeState) doFullHandshake() error {
skx, ok := msg.(*serverKeyExchangeMsg)
if ok {
hs.writeServerHash(skx.marshal())
- err = keyAgreement.processServerKeyExchange(c.config, hs.hello, hs.serverHello, certs[0], skx)
+ err = keyAgreement.processServerKeyExchange(c.config, hs.hello, hs.serverHello, leaf, skx)
if err != nil {
c.sendAlert(alertUnexpectedMessage)
return err
@@ -488,7 +493,7 @@ func (hs *clientHandshakeState) doFullHandshake() error {
// Certificate message, even if it's empty because we don't have a
// certificate to send.
if certRequested {
- certMsg = new(certificateMsg)
+ certMsg := new(certificateMsg)
if chainToSend != nil {
certMsg.certificates = chainToSend.Certificate
}
@@ -496,7 +501,7 @@ func (hs *clientHandshakeState) doFullHandshake() error {
c.writeRecord(recordTypeHandshake, certMsg.marshal())
}
- preMasterSecret, ckx, err := keyAgreement.generateClientKeyExchange(c.config, hs.hello, certs[0])
+ preMasterSecret, ckx, err := keyAgreement.generateClientKeyExchange(c.config, hs.hello, leaf)
if err != nil {
c.sendAlert(alertInternalError)
return err
diff --git a/ssl/test/runner/handshake_server.go b/ssl/test/runner/handshake_server.go
index 645a67c..4bf8f1c 100644
--- a/ssl/test/runner/handshake_server.go
+++ b/ssl/test/runner/handshake_server.go
@@ -383,7 +383,8 @@ func (hs *serverHandshakeState) doFullHandshake() error {
config := hs.c.config
c := hs.c
- if hs.clientHello.ocspStapling && len(hs.cert.OCSPStaple) > 0 {
+ isPSK := hs.suite.flags&suitePSK != 0
+ if !isPSK && hs.clientHello.ocspStapling && len(hs.cert.OCSPStaple) > 0 {
hs.hello.ocspStapling = true
}
@@ -397,11 +398,13 @@ func (hs *serverHandshakeState) doFullHandshake() error {
c.writeRecord(recordTypeHandshake, hs.hello.marshal())
- certMsg := new(certificateMsg)
- certMsg.certificates = hs.cert.Certificate
- if !config.Bugs.UnauthenticatedECDH {
- hs.writeServerHash(certMsg.marshal())
- c.writeRecord(recordTypeHandshake, certMsg.marshal())
+ if !isPSK {
+ certMsg := new(certificateMsg)
+ certMsg.certificates = hs.cert.Certificate
+ if !config.Bugs.UnauthenticatedECDH {
+ hs.writeServerHash(certMsg.marshal())
+ c.writeRecord(recordTypeHandshake, certMsg.marshal())
+ }
}
if hs.hello.ocspStapling {
@@ -466,6 +469,7 @@ func (hs *serverHandshakeState) doFullHandshake() error {
// If we requested a client certificate, then the client must send a
// certificate message, even if it's empty.
if config.ClientAuth >= RequestClientCert {
+ var certMsg *certificateMsg
if certMsg, ok = msg.(*certificateMsg); !ok {
c.sendAlert(alertUnexpectedMessage)
return unexpectedMessageError(certMsg, msg)
diff --git a/ssl/test/runner/key_agreement.go b/ssl/test/runner/key_agreement.go
index f8ba1f8..4f76cb1 100644
--- a/ssl/test/runner/key_agreement.go
+++ b/ssl/test/runner/key_agreement.go
@@ -586,3 +586,90 @@ func (ka *dheKeyAgreement) generateClientKeyExchange(config *Config, clientHello
return preMasterSecret, ckx, nil
}
+
+// makePSKPremaster formats a PSK pre-master secret based on
+// otherSecret from the base key exchange and psk.
+func makePSKPremaster(otherSecret, psk []byte) []byte {
+ out := make([]byte, 0, 2+len(otherSecret)+2+len(psk))
+ out = append(out, byte(len(otherSecret)>>8), byte(len(otherSecret)))
+ out = append(out, otherSecret...)
+ out = append(out, byte(len(psk)>>8), byte(len(psk)))
+ out = append(out, psk...)
+ return out
+}
+
+// pskKeyAgreement implements the PSK key agreement.
+type pskKeyAgreement struct {
+ identityHint string
+}
+
+func (ka *pskKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
+ // ServerKeyExchange is optional if the identity hint is empty.
+ if config.PreSharedKeyIdentity == "" {
+ return nil, nil
+ }
+ bytes := make([]byte, 2+len(config.PreSharedKeyIdentity))
+ bytes[0] = byte(len(config.PreSharedKeyIdentity) >> 8)
+ bytes[1] = byte(len(config.PreSharedKeyIdentity))
+ copy(bytes[2:], []byte(config.PreSharedKeyIdentity))
+
+ skx := new(serverKeyExchangeMsg)
+ skx.key = bytes
+ return skx, nil
+}
+
+func (ka *pskKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
+ if len(ckx.ciphertext) < 2 {
+ return nil, errClientKeyExchange
+ }
+ identityLen := (int(ckx.ciphertext[0]) << 8) | int(ckx.ciphertext[1])
+ if 2+identityLen != len(ckx.ciphertext) {
+ return nil, errClientKeyExchange
+ }
+ identity := string(ckx.ciphertext[2:])
+
+ if identity != config.PreSharedKeyIdentity {
+ return nil, errors.New("tls: unexpected identity")
+ }
+
+ if config.PreSharedKey == nil {
+ return nil, errors.New("tls: pre-shared key not configured")
+ }
+ otherSecret := make([]byte, len(config.PreSharedKey))
+ return makePSKPremaster(otherSecret, config.PreSharedKey), nil
+}
+
+func (ka *pskKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error {
+ if len(skx.key) < 2 {
+ return errServerKeyExchange
+ }
+ identityLen := (int(skx.key[0]) << 8) | int(skx.key[1])
+ if 2+identityLen != len(skx.key) {
+ return errServerKeyExchange
+ }
+ ka.identityHint = string(skx.key[2:])
+ return nil
+}
+
+func (ka *pskKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
+ // The server only sends an identity hint but, for purposes of
+ // test code, the server always sends the hint and it is
+ // required to match.
+ if ka.identityHint != config.PreSharedKeyIdentity {
+ return nil, nil, errors.New("tls: unexpected identity")
+ }
+
+ bytes := make([]byte, 2+len(config.PreSharedKeyIdentity))
+ bytes[0] = byte(len(config.PreSharedKeyIdentity) >> 8)
+ bytes[1] = byte(len(config.PreSharedKeyIdentity))
+ copy(bytes[2:], []byte(config.PreSharedKeyIdentity))
+
+ ckx := new(clientKeyExchangeMsg)
+ ckx.ciphertext = bytes
+
+ if config.PreSharedKey == nil {
+ return nil, nil, errors.New("tls: pre-shared key not configured")
+ }
+ otherSecret := make([]byte, len(config.PreSharedKey))
+ return makePSKPremaster(otherSecret, config.PreSharedKey), ckx, nil
+}
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
index 10f86c9..6f4562a 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -835,6 +835,9 @@ var testCipherSuites = []struct {
{"ECDHE-RSA-AES256-SHA", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA},
{"ECDHE-RSA-AES256-SHA384", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384},
{"ECDHE-RSA-RC4-SHA", TLS_ECDHE_RSA_WITH_RC4_128_SHA},
+ {"PSK-AES128-CBC-SHA", TLS_PSK_WITH_AES_128_CBC_SHA},
+ {"PSK-AES256-CBC-SHA", TLS_PSK_WITH_AES_256_CBC_SHA},
+ {"PSK-RC4-SHA", TLS_PSK_WITH_RC4_128_SHA},
{"RC4-MD5", TLS_RSA_WITH_RC4_128_MD5},
{"RC4-SHA", TLS_RSA_WITH_RC4_128_SHA},
}
@@ -847,6 +850,9 @@ func isTLS12Only(suiteName string) bool {
func addCipherSuiteTests() {
for _, suite := range testCipherSuites {
+ const psk = "12345"
+ const pskIdentity = "luggage combo"
+
var cert Certificate
var certFile string
var keyFile string
@@ -860,6 +866,13 @@ func addCipherSuiteTests() {
keyFile = rsaKeyFile
}
+ var flags []string
+ if strings.HasPrefix(suite.name, "PSK-") || strings.Contains(suite.name, "-PSK-") {
+ flags = append(flags,
+ "-psk", psk,
+ "-psk-identity", pskIdentity)
+ }
+
for _, ver := range tlsVersions {
if ver.version < VersionTLS12 && isTLS12Only(suite.name) {
continue
@@ -874,11 +887,14 @@ func addCipherSuiteTests() {
testType: clientTest,
name: ver.name + "-" + suite.name + "-client",
config: Config{
- MinVersion: ver.version,
- MaxVersion: ver.version,
- CipherSuites: []uint16{suite.id},
- Certificates: []Certificate{cert},
+ MinVersion: ver.version,
+ MaxVersion: ver.version,
+ CipherSuites: []uint16{suite.id},
+ Certificates: []Certificate{cert},
+ PreSharedKey: []byte(psk),
+ PreSharedKeyIdentity: pskIdentity,
},
+ flags: flags,
resumeSession: resumeSession,
})
@@ -886,13 +902,16 @@ func addCipherSuiteTests() {
testType: serverTest,
name: ver.name + "-" + suite.name + "-server",
config: Config{
- MinVersion: ver.version,
- MaxVersion: ver.version,
- CipherSuites: []uint16{suite.id},
- Certificates: []Certificate{cert},
+ MinVersion: ver.version,
+ MaxVersion: ver.version,
+ CipherSuites: []uint16{suite.id},
+ Certificates: []Certificate{cert},
+ PreSharedKey: []byte(psk),
+ PreSharedKeyIdentity: pskIdentity,
},
certFile: certFile,
keyFile: keyFile,
+ flags: flags,
resumeSession: resumeSession,
})
@@ -903,11 +922,14 @@ func addCipherSuiteTests() {
protocol: dtls,
name: "D" + ver.name + "-" + suite.name + "-client",
config: Config{
- MinVersion: ver.version,
- MaxVersion: ver.version,
- CipherSuites: []uint16{suite.id},
- Certificates: []Certificate{cert},
+ MinVersion: ver.version,
+ MaxVersion: ver.version,
+ CipherSuites: []uint16{suite.id},
+ Certificates: []Certificate{cert},
+ PreSharedKey: []byte(psk),
+ PreSharedKeyIdentity: pskIdentity,
},
+ flags: flags,
resumeSession: resumeSession,
})
testCases = append(testCases, testCase{
@@ -915,13 +937,16 @@ func addCipherSuiteTests() {
protocol: dtls,
name: "D" + ver.name + "-" + suite.name + "-server",
config: Config{
- MinVersion: ver.version,
- MaxVersion: ver.version,
- CipherSuites: []uint16{suite.id},
- Certificates: []Certificate{cert},
+ MinVersion: ver.version,
+ MaxVersion: ver.version,
+ CipherSuites: []uint16{suite.id},
+ Certificates: []Certificate{cert},
+ PreSharedKey: []byte(psk),
+ PreSharedKeyIdentity: pskIdentity,
},
certFile: certFile,
keyFile: keyFile,
+ flags: flags,
resumeSession: resumeSession,
})
}
@@ -1115,8 +1140,8 @@ func addExtendedMasterSecretTests() {
RequireExtendedMasterSecret: with,
},
},
- flags: flags,
- shouldFail: ver.version == VersionSSL30 && with,
+ flags: flags,
+ shouldFail: ver.version == VersionSSL30 && with,
}
if test.shouldFail {
test.expectedLocalError = "extended master secret required but not supported by peer"
@@ -1248,6 +1273,34 @@ func addStateMachineCoverageTests(async, splitHandshake bool, protocol protocol)
flags: flags,
})
+ // Skip ServerKeyExchange in PSK key exchange if there's no
+ // identity hint.
+ testCases = append(testCases, testCase{
+ protocol: protocol,
+ name: "EmptyPSKHint-Client" + suffix,
+ config: Config{
+ CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA},
+ PreSharedKey: []byte("secret"),
+ Bugs: ProtocolBugs{
+ MaxHandshakeRecordLength: maxHandshakeRecordLength,
+ },
+ },
+ flags: append(flags, "-psk", "secret"),
+ })
+ testCases = append(testCases, testCase{
+ protocol: protocol,
+ testType: serverTest,
+ name: "EmptyPSKHint-Server" + suffix,
+ config: Config{
+ CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA},
+ PreSharedKey: []byte("secret"),
+ Bugs: ProtocolBugs{
+ MaxHandshakeRecordLength: maxHandshakeRecordLength,
+ },
+ },
+ flags: append(flags, "-psk", "secret"),
+ })
+
if protocol == tls {
// NPN on client and server; results in post-handshake message.
testCases = append(testCases, testCase{
diff --git a/ssl/test/test_config.cc b/ssl/test/test_config.cc
index 737c78d..c50d9de 100644
--- a/ssl/test/test_config.cc
+++ b/ssl/test/test_config.cc
@@ -76,6 +76,8 @@ const StringFlag kStringFlags[] = {
{ "-expect-alpn", &TestConfig::expected_alpn },
{ "-expect-advertised-alpn", &TestConfig::expected_advertised_alpn },
{ "-select-alpn", &TestConfig::select_alpn },
+ { "-psk", &TestConfig::psk },
+ { "-psk-identity", &TestConfig::psk_identity },
};
const size_t kNumStringFlags = sizeof(kStringFlags) / sizeof(kStringFlags[0]);
diff --git a/ssl/test/test_config.h b/ssl/test/test_config.h
index d7f1be8..e5ff8ad 100644
--- a/ssl/test/test_config.h
+++ b/ssl/test/test_config.h
@@ -54,6 +54,8 @@ struct TestConfig {
std::string select_alpn;
bool expect_session_miss;
bool expect_extended_master_secret;
+ std::string psk;
+ std::string psk_identity;
};
bool ParseConfig(int argc, char **argv, TestConfig *out_config);