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/1741053v1.2.3
@@ -85,6 +85,9 @@ type Config struct { | |||||
// NextProtos is a list of supported, application level protocols. | // NextProtos is a list of supported, application level protocols. | ||||
// Currently only server-side handling is supported. | // Currently only server-side handling is supported. | ||||
NextProtos []string | NextProtos []string | ||||
// ServerName is included in the client's handshake to support virtual | |||||
// hosting. | |||||
ServerName string | |||||
} | } | ||||
type Certificate struct { | type Certificate struct { | ||||
@@ -5,6 +5,7 @@ package tls | |||||
import ( | import ( | ||||
"bytes" | "bytes" | ||||
"crypto/subtle" | "crypto/subtle" | ||||
"crypto/x509" | |||||
"hash" | "hash" | ||||
"io" | "io" | ||||
"net" | "net" | ||||
@@ -27,6 +28,7 @@ type Conn struct { | |||||
handshakeComplete bool | handshakeComplete bool | ||||
cipherSuite uint16 | cipherSuite uint16 | ||||
ocspResponse []byte // stapled OCSP response | ocspResponse []byte // stapled OCSP response | ||||
peerCertificates []*x509.Certificate | |||||
clientProtocol string | clientProtocol string | ||||
@@ -651,3 +653,12 @@ func (c *Conn) OCSPResponse() []byte { | |||||
return c.ocspResponse | 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 | |||||
} |
@@ -28,6 +28,7 @@ func (c *Conn) clientHandshake() os.Error { | |||||
compressionMethods: []uint8{compressionNone}, | compressionMethods: []uint8{compressionNone}, | ||||
random: make([]byte, 32), | random: make([]byte, 32), | ||||
ocspStapling: true, | ocspStapling: true, | ||||
serverName: c.config.ServerName, | |||||
} | } | ||||
t := uint32(c.config.Time()) | t := uint32(c.config.Time()) | ||||
@@ -107,6 +108,8 @@ func (c *Conn) clientHandshake() os.Error { | |||||
return c.sendAlert(alertUnsupportedCertificate) | return c.sendAlert(alertUnsupportedCertificate) | ||||
} | } | ||||
c.peerCertificates = certs | |||||
if serverHello.certStatus { | if serverHello.certStatus { | ||||
msg, err = c.readHandshake() | msg, err = c.readHandshake() | ||||
if err != nil { | if err != nil { | ||||
@@ -100,7 +100,8 @@ func (m *clientHelloMsg) marshal() []byte { | |||||
// ServerName server_name_list<1..2^16-1> | // ServerName server_name_list<1..2^16-1> | ||||
// } ServerNameList; | // } 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[3] = byte(len(m.serverName) >> 8) | ||||
z[4] = byte(len(m.serverName)) | z[4] = byte(len(m.serverName)) | ||||
copy(z[5:], []byte(m.serverName)) | copy(z[5:], []byte(m.serverName)) | ||||