]> Cypherpunks repositories - gostls13.git/commitdiff
crypto/tls: add client-side SNI support and PeerCertificates.
authorAdam Langley <agl@golang.org>
Wed, 21 Jul 2010 15:36:01 +0000 (11:36 -0400)
committerAdam Langley <agl@golang.org>
Wed, 21 Jul 2010 15:36:01 +0000 (11:36 -0400)
SNI (Server Name Indication) is a way for a TLS client to
indicate to the server which name it knows the server by. This
allows the server to have several names and return the correct
certificate for each (virtual hosting).

PeerCertificates returns the list of certificates presented by
server.

R=r
CC=golang-dev
https://golang.org/cl/1741053

src/pkg/crypto/tls/common.go
src/pkg/crypto/tls/conn.go
src/pkg/crypto/tls/handshake_client.go
src/pkg/crypto/tls/handshake_messages.go

index 7c6940aa32be3ede8a5e2581f8be2e97804f80e4..717ae0a81539a3107385db1c73b1452f6d0b0a49 100644 (file)
@@ -85,6 +85,9 @@ type Config struct {
        // NextProtos is a list of supported, application level protocols.
        // Currently only server-side handling is supported.
        NextProtos []string
+       // ServerName is included in the client's handshake to support virtual
+       // hosting.
+       ServerName string
 }
 
 type Certificate struct {
index aa224e49d2275b66fcf978723828f271f69f6990..7f5d97d4be914338367c28251816bb1a379edf08 100644 (file)
@@ -5,6 +5,7 @@ package tls
 import (
        "bytes"
        "crypto/subtle"
+       "crypto/x509"
        "hash"
        "io"
        "net"
@@ -27,6 +28,7 @@ type Conn struct {
        handshakeComplete bool
        cipherSuite       uint16
        ocspResponse      []byte // stapled OCSP response
+       peerCertificates  []*x509.Certificate
 
        clientProtocol string
 
@@ -651,3 +653,12 @@ func (c *Conn) OCSPResponse() []byte {
 
        return c.ocspResponse
 }
+
+// PeerCertificates returns the certificate chain that was presented by the
+// other side.
+func (c *Conn) PeerCertificates() []*x509.Certificate {
+       c.handshakeMutex.Lock()
+       defer c.handshakeMutex.Unlock()
+
+       return c.peerCertificates
+}
index b3b597327fc90a5c6bbe4ec6571f8c91a8aaa478..324c02f701c5723993a7ba1b9be810fb54bafaef 100644 (file)
@@ -28,6 +28,7 @@ func (c *Conn) clientHandshake() os.Error {
                compressionMethods: []uint8{compressionNone},
                random:             make([]byte, 32),
                ocspStapling:       true,
+               serverName:         c.config.ServerName,
        }
 
        t := uint32(c.config.Time())
@@ -107,6 +108,8 @@ func (c *Conn) clientHandshake() os.Error {
                return c.sendAlert(alertUnsupportedCertificate)
        }
 
+       c.peerCertificates = certs
+
        if serverHello.certStatus {
                msg, err = c.readHandshake()
                if err != nil {
index 13c05fe574d67ed20ad66604974d4649cd0dad8a..6d4e5c70944e6b71828b0b7bbc63a938fc429a45 100644 (file)
@@ -100,7 +100,8 @@ func (m *clientHelloMsg) marshal() []byte {
                //     ServerName server_name_list<1..2^16-1>
                // } ServerNameList;
 
-               z[1] = 1
+               z[0] = byte((len(m.serverName) + 3) >> 8)
+               z[1] = byte(len(m.serverName) + 3)
                z[3] = byte(len(m.serverName) >> 8)
                z[4] = byte(len(m.serverName))
                copy(z[5:], []byte(m.serverName))