crypto/tls: add client-side SNI support and PeerCertificates.
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
This commit is contained in:
parent
a54a4371e7
commit
cbf5c897cb
@ -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 {
|
||||||
|
11
conn.go
11
conn.go
@ -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))
|
||||||
|
Loading…
Reference in New Issue
Block a user