Add support for sending TLS 1.3 tickets in Go.

Also parse out the ticket lifetime which was previously ignored.

BUG=75

Change-Id: I6ba92017bd4f1b31da55fd85d2af529fd592de11
Reviewed-on: https://boringssl-review.googlesource.com/8871
Reviewed-by: Nick Harper <nharper@chromium.org>
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/ssl/test/runner/conn.go b/ssl/test/runner/conn.go
index 1b6c557..8658fd2 100644
--- a/ssl/test/runner/conn.go
+++ b/ssl/test/runner/conn.go
@@ -59,6 +59,7 @@
 
 	clientRandom, serverRandom [32]byte
 	exporterSecret             []byte
+	resumptionSecret           []byte
 
 	clientProtocol         string
 	clientProtocolFallback bool
@@ -1143,7 +1144,9 @@
 	case typeHelloRetryRequest:
 		m = new(helloRetryRequestMsg)
 	case typeNewSessionTicket:
-		m = new(newSessionTicketMsg)
+		m = &newSessionTicketMsg{
+			version: c.vers,
+		}
 	case typeEncryptedExtensions:
 		m = new(encryptedExtensionsMsg)
 	case typeCertificate:
@@ -1582,3 +1585,39 @@
 	}
 	return false
 }
+
+func (c *Conn) SendNewSessionTicket() error {
+	if c.isClient || c.vers < VersionTLS13 {
+		return errors.New("tls: cannot send post-handshake NewSessionTicket")
+	}
+
+	var peerCertificatesRaw [][]byte
+	for _, cert := range c.peerCertificates {
+		peerCertificatesRaw = append(peerCertificatesRaw, cert.Raw)
+	}
+	state := sessionState{
+		vers:         c.vers,
+		cipherSuite:  c.cipherSuite.id,
+		masterSecret: c.resumptionSecret,
+		certificates: peerCertificatesRaw,
+	}
+
+	// TODO(davidben): Allow configuring these values.
+	m := &newSessionTicketMsg{
+		version:        c.vers,
+		ticketLifetime: uint32(24 * time.Hour / time.Second),
+		ticketFlags:    ticketAllowDHEResumption | ticketAllowPSKResumption,
+	}
+	if !c.config.Bugs.SendEmptySessionTicket {
+		var err error
+		m.ticket, err = c.encryptTicket(&state)
+		if err != nil {
+			return err
+		}
+	}
+
+	c.out.Lock()
+	defer c.out.Unlock()
+	_, err := c.writeRecord(recordTypeHandshake, m.marshal())
+	return err
+}