summaryrefslogtreecommitdiffstats
path: root/src/ssl/test/runner/handshake_client.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/ssl/test/runner/handshake_client.go')
-rw-r--r--src/ssl/test/runner/handshake_client.go111
1 files changed, 78 insertions, 33 deletions
diff --git a/src/ssl/test/runner/handshake_client.go b/src/ssl/test/runner/handshake_client.go
index f297fc1..0dac05d 100644
--- a/src/ssl/test/runner/handshake_client.go
+++ b/src/ssl/test/runner/handshake_client.go
@@ -6,7 +6,6 @@ package main
import (
"bytes"
- "crypto"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rsa"
@@ -22,13 +21,14 @@ import (
)
type clientHandshakeState struct {
- c *Conn
- serverHello *serverHelloMsg
- hello *clientHelloMsg
- suite *cipherSuite
- finishedHash finishedHash
- masterSecret []byte
- session *ClientSessionState
+ c *Conn
+ serverHello *serverHelloMsg
+ hello *clientHelloMsg
+ suite *cipherSuite
+ finishedHash finishedHash
+ masterSecret []byte
+ session *ClientSessionState
+ finishedBytes []byte
}
func (c *Conn) clientHandshake() error {
@@ -83,6 +83,10 @@ func (c *Conn) clientHandshake() error {
hello.extendedMasterSecret = false
}
+ if c.config.Bugs.NoSupportedCurves {
+ hello.supportedCurves = nil
+ }
+
if len(c.clientVerify) > 0 && !c.config.Bugs.EmptyRenegotiationInfo {
if c.config.Bugs.BadRenegotiationInfo {
hello.secureRenegotiation = append(hello.secureRenegotiation, c.clientVerify...)
@@ -129,13 +133,16 @@ NextCipherSuite:
return errors.New("tls: short read from Rand: " + err.Error())
}
- if hello.vers >= VersionTLS12 && !c.config.Bugs.NoSignatureAndHashes {
+ if hello.vers >= VersionTLS12 && !c.config.Bugs.NoSignatureAndHashes && (c.cipherSuite == nil || !c.config.Bugs.NoSignatureAlgorithmsOnRenego) {
hello.signatureAndHashes = c.config.signatureAndHashesForClient()
}
var session *ClientSessionState
var cacheKey string
sessionCache := c.config.ClientSessionCache
+ if c.config.Bugs.NeverResumeOnRenego && c.cipherSuite != nil {
+ sessionCache = nil
+ }
if sessionCache != nil {
hello.ticketSupported = !c.config.SessionTicketsDisabled
@@ -213,7 +220,11 @@ NextCipherSuite:
helloBytes = hello.marshal()
c.writeRecord(recordTypeHandshake, helloBytes)
}
+ c.dtlsFlushHandshake()
+ if err := c.simulatePacketLoss(nil); err != nil {
+ return err
+ }
msg, err := c.readHandshake()
if err != nil {
return err
@@ -233,7 +244,11 @@ NextCipherSuite:
hello.cookie = helloVerifyRequest.cookie
helloBytes = hello.marshal()
c.writeRecord(recordTypeHandshake, helloBytes)
+ c.dtlsFlushHandshake()
+ if err := c.simulatePacketLoss(nil); err != nil {
+ return err
+ }
msg, err = c.readHandshake()
if err != nil {
return err
@@ -317,6 +332,15 @@ NextCipherSuite:
if err := hs.sendFinished(isResume); err != nil {
return err
}
+ // Most retransmits are triggered by a timeout, but the final
+ // leg of the handshake is retransmited upon re-receiving a
+ // Finished.
+ if err := c.simulatePacketLoss(func() {
+ c.writeRecord(recordTypeHandshake, hs.finishedBytes)
+ c.dtlsFlushHandshake()
+ }); err != nil {
+ return err
+ }
if err := hs.readSessionTicket(); err != nil {
return err
}
@@ -331,7 +355,10 @@ NextCipherSuite:
c.didResume = isResume
c.handshakeComplete = true
- c.cipherSuite = suite.id
+ c.cipherSuite = suite
+ copy(c.clientRandom[:], hs.hello.random)
+ copy(c.serverRandom[:], hs.serverHello.random)
+ copy(c.masterSecret[:], hs.masterSecret)
return nil
}
@@ -559,33 +586,39 @@ func (hs *clientHandshakeState) doFullHandshake() error {
hasSignatureAndHash: c.vers >= VersionTLS12,
}
+ // Determine the hash to sign.
+ var signatureType uint8
+ switch c.config.Certificates[0].PrivateKey.(type) {
+ case *ecdsa.PrivateKey:
+ signatureType = signatureECDSA
+ case *rsa.PrivateKey:
+ signatureType = signatureRSA
+ default:
+ c.sendAlert(alertInternalError)
+ return errors.New("unknown private key type")
+ }
+ if c.config.Bugs.IgnorePeerSignatureAlgorithmPreferences {
+ certReq.signatureAndHashes = c.config.signatureAndHashesForClient()
+ }
+ certVerify.signatureAndHash, err = hs.finishedHash.selectClientCertSignatureAlgorithm(certReq.signatureAndHashes, c.config.signatureAndHashesForClient(), signatureType)
+ if err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
+ digest, hashFunc, err := hs.finishedHash.hashForClientCertificate(certVerify.signatureAndHash, hs.masterSecret)
+ if err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
+
switch key := c.config.Certificates[0].PrivateKey.(type) {
case *ecdsa.PrivateKey:
- certVerify.signatureAndHash, err = hs.finishedHash.selectClientCertSignatureAlgorithm(certReq.signatureAndHashes, signatureECDSA)
- if err != nil {
- break
- }
- var digest []byte
- digest, _, err = hs.finishedHash.hashForClientCertificate(certVerify.signatureAndHash, hs.masterSecret)
- if err != nil {
- break
- }
var r, s *big.Int
r, s, err = ecdsa.Sign(c.config.rand(), key, digest)
if err == nil {
signed, err = asn1.Marshal(ecdsaSignature{r, s})
}
case *rsa.PrivateKey:
- certVerify.signatureAndHash, err = hs.finishedHash.selectClientCertSignatureAlgorithm(certReq.signatureAndHashes, signatureRSA)
- if err != nil {
- break
- }
- var digest []byte
- var hashFunc crypto.Hash
- digest, hashFunc, err = hs.finishedHash.hashForClientCertificate(certVerify.signatureAndHash, hs.masterSecret)
- if err != nil {
- break
- }
signed, err = rsa.SignPKCS1v15(c.config.rand(), key, hashFunc, digest)
default:
err = errors.New("unknown private key type")
@@ -599,6 +632,7 @@ func (hs *clientHandshakeState) doFullHandshake() error {
hs.writeClientHash(certVerify.marshal())
c.writeRecord(recordTypeHandshake, certVerify.marshal())
}
+ c.dtlsFlushHandshake()
hs.finishedHash.discardHandshakeBuffer()
@@ -825,15 +859,19 @@ func (hs *clientHandshakeState) sendFinished(isResume bool) error {
} else {
finished.verifyData = hs.finishedHash.clientSum(hs.masterSecret)
}
+ if c.config.Bugs.BadFinished {
+ finished.verifyData[0]++
+ }
c.clientVerify = append(c.clientVerify[:0], finished.verifyData...)
- finishedBytes := finished.marshal()
- hs.writeHash(finishedBytes, seqno)
- postCCSBytes = append(postCCSBytes, finishedBytes...)
+ hs.finishedBytes = finished.marshal()
+ hs.writeHash(hs.finishedBytes, seqno)
+ postCCSBytes = append(postCCSBytes, hs.finishedBytes...)
if c.config.Bugs.FragmentAcrossChangeCipherSpec {
c.writeRecord(recordTypeHandshake, postCCSBytes[:5])
postCCSBytes = postCCSBytes[5:]
}
+ c.dtlsFlushHandshake()
if !c.config.Bugs.SkipChangeCipherSpec &&
c.config.Bugs.EarlyChangeCipherSpec == 0 {
@@ -843,8 +881,15 @@ func (hs *clientHandshakeState) sendFinished(isResume bool) error {
if c.config.Bugs.AppDataAfterChangeCipherSpec != nil {
c.writeRecord(recordTypeApplicationData, c.config.Bugs.AppDataAfterChangeCipherSpec)
}
+ if c.config.Bugs.AlertAfterChangeCipherSpec != 0 {
+ c.sendAlert(c.config.Bugs.AlertAfterChangeCipherSpec)
+ return errors.New("tls: simulating post-CCS alert")
+ }
- c.writeRecord(recordTypeHandshake, postCCSBytes)
+ if !c.config.Bugs.SkipFinished {
+ c.writeRecord(recordTypeHandshake, postCCSBytes)
+ c.dtlsFlushHandshake()
+ }
return nil
}