Enforce the SSL 3.0 no_certificate alert in tests.
As long as we still have this code, we should make sure it doesn't
regress.
Change-Id: I0290792aedcf667ec49b251d747ffbc141c0cec4
Reviewed-on: https://boringssl-review.googlesource.com/13053
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/test/runner/alert.go b/ssl/test/runner/alert.go
index 93de4b5..652e9ee 100644
--- a/ssl/test/runner/alert.go
+++ b/ssl/test/runner/alert.go
@@ -23,7 +23,7 @@
alertRecordOverflow alert = 22
alertDecompressionFailure alert = 30
alertHandshakeFailure alert = 40
- alertNoCertficate alert = 41
+ alertNoCertificate alert = 41
alertBadCertificate alert = 42
alertUnsupportedCertificate alert = 43
alertCertificateRevoked alert = 44
@@ -56,6 +56,7 @@
alertRecordOverflow: "record overflow",
alertDecompressionFailure: "decompression failure",
alertHandshakeFailure: "handshake failure",
+ alertNoCertificate: "no certificate",
alertBadCertificate: "bad certificate",
alertUnsupportedCertificate: "unsupported certificate",
alertCertificateRevoked: "revoked certificate",
diff --git a/ssl/test/runner/conn.go b/ssl/test/runner/conn.go
index 510bcf7..3e22465 100644
--- a/ssl/test/runner/conn.go
+++ b/ssl/test/runner/conn.go
@@ -21,6 +21,8 @@
"time"
)
+var errNoCertificateAlert = errors.New("tls: no certificate alert")
+
// A Conn represents a secured connection.
// It implements the net.Conn interface.
type Conn struct {
@@ -895,6 +897,11 @@
}
switch data[0] {
case alertLevelWarning:
+ if alert(data[1]) == alertNoCertificate {
+ c.in.freeBlock(b)
+ return errNoCertificateAlert
+ }
+
// drop on the floor
c.in.freeBlock(b)
goto Again
@@ -963,7 +970,7 @@
// L < c.out.Mutex.
func (c *Conn) sendAlert(err alert) error {
level := byte(alertLevelError)
- if err == alertNoRenegotiation || err == alertCloseNotify || err == alertNoCertficate {
+ if err == alertNoRenegotiation || err == alertCloseNotify || err == alertNoCertificate {
level = alertLevelWarning
}
return c.SendAlert(level, err)
@@ -1195,6 +1202,13 @@
// c.in.Mutex < L; c.out.Mutex < L.
func (c *Conn) readHandshake() (interface{}, error) {
data, err := c.doReadHandshake()
+ if err == errNoCertificateAlert {
+ if c.hand.Len() != 0 {
+ // The warning alert may not interleave with a handshake message.
+ return nil, c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
+ }
+ return new(ssl3NoCertificateMsg), nil
+ }
if err != nil {
return nil, err
}
diff --git a/ssl/test/runner/handshake_client.go b/ssl/test/runner/handshake_client.go
index 4e715b5..507ea40 100644
--- a/ssl/test/runner/handshake_client.go
+++ b/ssl/test/runner/handshake_client.go
@@ -1028,7 +1028,7 @@
// no_certificate warning alert.
if certRequested {
if c.vers == VersionSSL30 && chainToSend == nil {
- c.sendAlert(alertNoCertficate)
+ c.sendAlert(alertNoCertificate)
} else if !c.config.Bugs.SkipClientCertificate {
certMsg := new(certificateMsg)
if chainToSend != nil {
diff --git a/ssl/test/runner/handshake_messages.go b/ssl/test/runner/handshake_messages.go
index 0d4d161..01f673b 100644
--- a/ssl/test/runner/handshake_messages.go
+++ b/ssl/test/runner/handshake_messages.go
@@ -2275,6 +2275,10 @@
return m.keyUpdateRequest == keyUpdateNotRequested || m.keyUpdateRequest == keyUpdateRequested
}
+// ssl3NoCertificateMsg is a dummy message to handle SSL 3.0 using a warning
+// alert in the handshake.
+type ssl3NoCertificateMsg struct{}
+
func eqUint16s(x, y []uint16) bool {
if len(x) != len(y) {
return false
diff --git a/ssl/test/runner/handshake_server.go b/ssl/test/runner/handshake_server.go
index 8f4e97b..1116d6c 100644
--- a/ssl/test/runner/handshake_server.go
+++ b/ssl/test/runner/handshake_server.go
@@ -1452,7 +1452,13 @@
for _, cert := range certMsg.certificates {
certificates = append(certificates, cert.data)
}
- } else if c.vers != VersionSSL30 {
+ } else if c.vers == VersionSSL30 {
+ // In SSL 3.0, no certificate is signaled by a warning
+ // alert which we translate to ssl3NoCertificateMsg.
+ if _, ok := msg.(*ssl3NoCertificateMsg); !ok {
+ return errors.New("tls: client provided neither a certificate nor no_certificate warning alert")
+ }
+ } else {
// In TLS, the Certificate message is required. In SSL
// 3.0, the peer skips it when sending no certificates.
c.sendAlert(alertUnexpectedMessage)
@@ -1473,11 +1479,9 @@
return err
}
- if ok {
- msg, err = c.readHandshake()
- if err != nil {
- return err
- }
+ msg, err = c.readHandshake()
+ if err != nil {
+ return err
}
}