- tls
tls
tls包实现了TLS 1.2,细节参见RFC 5246。
Constants
const (
TLS_RSA_WITH_RC4_128_SHA uint16 = 0x0005
TLS_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x000a
TLS_RSA_WITH_AES_128_CBC_SHA uint16 = 0x002f
TLS_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0035
TLS_ECDHE_ECDSA_WITH_RC4_128_SHA uint16 = 0xc007
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA uint16 = 0xc009
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA uint16 = 0xc00a
TLS_ECDHE_RSA_WITH_RC4_128_SHA uint16 = 0xc011
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xc012
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0xc013
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0xc014
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02f
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02b
)
可选的加密组的ID的列表。参见:http://www.iana.org/assignments/tls-parameters/tls-parameters.xml
const (
VersionSSL30 = 0x0300
VersionTLS10 = 0x0301
VersionTLS11 = 0x0302
VersionTLS12 = 0x0303
)
type ClientAuthType
type ClientAuthType int
ClientAuthType类型声明服务端将遵循的TLS客户端验证策略。
const (
NoClientCert ClientAuthType = iota
RequestClientCert
RequireAnyClientCert
VerifyClientCertIfGiven
RequireAndVerifyClientCert
)
type CurveID
type CurveID uint16
CurveID是TLS椭圆曲线的标识符的类型。
参见: http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-8
const (
CurveP256 CurveID = 23
CurveP384 CurveID = 24
CurveP521 CurveID = 25
)
type Certificate
type Certificate struct {
Certificate [][]byte
PrivateKey crypto.PrivateKey // 只支持rsa.PrivateKey和*ecdsa.PrivateKey类型
// OCSPStaple包含一个可选的OCSP staple的回复,当客户端要求时用于回复客户端
OCSPStaple []byte
// Leaf是解析后的叶证书,可以使用x509.ParseCertificate初始化,
// 以简化每次TLS客户端进行客户端认证时握手的过程。如果Leaf是nil,叶证书会根据需要解析。
Leaf *x509.Certificate
}
Certificate是一个或多个证书的链条,叶证书在最前面。
func LoadX509KeyPair
func LoadX509KeyPair(certFile, keyFile string) (cert Certificate, err error)
LoadX509KeyPair读取并解析一对文件获取公钥和私钥。这些文件必须是PEM编码的。
func X509KeyPair
func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (cert Certificate, err error)
X509KeyPair解析一对PEM编码的数据获取公钥和私钥。
type ClientSessionState
type ClientSessionState struct {
sessionTicket []uint8 // Encrypted ticket used for session resumption with server
vers uint16 // TLS version negotiated for the session
cipherSuite uint16 // Ciphersuite negotiated for the session
masterSecret []byte // Full handshake MasterSecret, or TLS 1.3 resumption_master_secret
serverCertificates []*x509.Certificate // Certificate chain presented by the server
verifiedChains [][]*x509.Certificate // Certificate chains we built for verification
receivedAt time.Time // When the session ticket was received from the server
ocspResponse []byte // Stapled OCSP response presented by the server
scts [][]byte // SCTs presented by the server
// TLS 1.3 fields.
nonce []byte // Ticket nonce sent by the server, to derive PSK
useBy time.Time // Expiration of the ticket lifetime as set by the server
ageAdd uint32 // Random obfuscation factor for sending the ticket age
}
ClientSessionState包含客户端所需的用于恢复TLS会话的状态。
type ClientSessionCache
type ClientSessionCache interface {
// Get搜索与给出的键相关联的*ClientSessionState并用ok说明是否找到
Get(sessionKey string) (session *ClientSessionState, ok bool)
// Put将*ClientSessionState与给出的键关联并写入缓存中
Put(sessionKey string, cs *ClientSessionState)
}
ClientSessionCache是ClientSessionState对象的缓存,可以被客户端用于恢复与某个服务端的TLS会话。本类型的实现期望被不同线程并行的调用。
func NewLRUClientSessionCache
func NewLRUClientSessionCache(capacity int) ClientSessionCache
函数使用给出的容量创建一个采用LRU策略的ClientSessionState,如果capacity<1会采用默认容量。
type Config
type Config struct {
// Rand提供用于生成随机数和RSA盲签名的熵源,该接口必须能安全的用于并发。
// 如果Rand是nil,会使用crypto/rand包的密码用随机数读取器。
Rand io.Reader
// Time返回当前时间,如果是nil会使用time.Now。
Time func() time.Time
// 不少于一个证书的链,用于提供给连接的另一端,服务端必须保证至少有一个证书。
Certificates []Certificate
// NameToCertificate映射证书名到证书。
// 注意证书名可以是"*.example.com "的格式,因此证书名不是必须为域名。
// 参见Config.BuildNameToCertificate方法。
// 如本字段为nil,Certificates字段的第一个成员会被用于所有连接。
NameToCertificate map[string]*Certificate
// RootCAs定义权威根证书,客户端会在验证服务端证书时用到本字段。
// 如果RootCAs是nil,TLS会使用主机的根CA池。
RootCAs *x509.CertPool
// 可以支持的应用层协议的列表
NextProtos []string
// 用于认证返回证书的主机名(除非设置了InsecureSkipVerify)。
// 也被用在客户端的握手里,以支持虚拟主机。
ServerName string
// ClientAuth决定服务端的认证策略,默认是NoClientCert。
ClientAuth ClientAuthType
// ClientCAs定义权威根证书,服务端会在采用ClientAuth策略时使用它来认证客户端证书。
ClientCAs *x509.CertPool
// InsecureSkipVerify控制客户端是否认证服务端的证书链和主机名。
// 如果InsecureSkipVerify为真,TLS连接会接受服务端提供的任何证书和该证书中的任何主机名。
// 此时,TLS连接容易遭受中间人攻击,这种设置只应用于测试。
InsecureSkipVerify bool
// CipherSuites是支持的加密组合列表。如果CipherSuites为nil,
// TLS连接会使用本包的实现支持的密码组合列表。
CipherSuites []uint16
// 本字段控制服务端是选择客户端最期望的密码组合还是服务端最期望的密码组合。
// 如果本字段为真,服务端会优先选择CipherSuites字段中靠前的密码组合使用。
PreferServerCipherSuites bool
// SessionTicketsDisabled可以设为假以关闭会话恢复支持。
SessionTicketsDisabled bool
// SessionTicketKey被TLS服务端用于提供哦你会话恢复服务,参见RFC 5077。
// 如果本字段为零值,它会在第一次服务端握手之前填写上随机数据。
//
// 如果多个服务端都在终止和同一主机的连接,它们应拥有相同的SessionTicketKey。
// 如果SessionTicketKey泄露了,使用该键的之前的记录和未来的TLS连接可能会被盗用。
SessionTicketKey [32]byte
// SessionCache是ClientSessionState的缓存,用于恢复TLS会话。
ClientSessionCache ClientSessionCache
// MinVersion包含可接受的最低SSL/TLS版本。如果为0,会将SSLv3作为最低版本。
MinVersion uint16
// MaxVersion包含可接受的最高SSL/TLS版本。
// 如果为0,会将本包使用的版本作为最高版本,目前是TLS 1.2。
MaxVersion uint16
// 本字段包含用于ECDHE握手的椭圆曲线的ID,按优先度排序。如为空,会使用默认值。
CurvePreferences []CurveID
// 内含隐藏或非导出字段
}
Config结构类型用于配置TLS客户端或服务端。在本类型的值提供给TLS函数后,就不应再修改该值。Config类型值可能被重用;tls包也不会修改它。
func (*Config) BuildNameToCertificate
func (c *Config) BuildNameToCertificate()
BuildNameToCertificate解析c.Certificates并将每一个叶证书的CommonName和SubjectAlternateName字段用于创建c.NameToCertificate。
type ConnectionState
type ConnectionState struct {
Version uint16 // 连接使用的TLS版本
HandshakeComplete bool // TLS握手是否完成
DidResume bool // 连接恢复了之前的TLS连接
CipherSuite uint16 // 使用的加密程序组合
NegotiatedProtocol string // 商定的下一层协议
NegotiatedProtocolIsMutual bool // 商定的协议是服务端建议的
ServerName string // 服务端名(仅服务端有)
PeerCertificates []*x509.Certificate // 远端提供的证书链
VerifiedChains [][]*x509.Certificate // 从PeerCertificates建立的认证链
}
ConnectionState类型记录连接的基本TLS细节。
type Conn
type Conn struct {
// constant
conn net.Conn
isClient bool
handshakeFn func() error // (*Conn).clientHandshake or serverHandshake
// handshakeStatus is 1 if the connection is currently transferring
// application data (i.e. is not currently processing a handshake).
// This field is only to be accessed with sync/atomic.
handshakeStatus uint32
// constant after handshake; protected by handshakeMutex
handshakeMutex sync.Mutex
handshakeErr error // error resulting from handshake
vers uint16 // TLS version
haveVers bool // version has been negotiated
config *Config // configuration passed to constructor
// handshakes counts the number of handshakes performed on the
// connection so far. If renegotiation is disabled then this is either
// zero or one.
handshakes int
didResume bool // whether this connection was a session resumption
cipherSuite uint16
ocspResponse []byte // stapled OCSP response
scts [][]byte // signed certificate timestamps from server
peerCertificates []*x509.Certificate
// verifiedChains contains the certificate chains that we built, as
// opposed to the ones presented by the server.
verifiedChains [][]*x509.Certificate
// serverName contains the server name indicated by the client, if any.
serverName string
// secureRenegotiation is true if the server echoed the secure
// renegotiation extension. (This is meaningless as a server because
// renegotiation is not supported in that case.)
secureRenegotiation bool
// ekm is a closure for exporting keying material.
ekm func(label string, context []byte, length int) ([]byte, error)
// resumptionSecret is the resumption_master_secret for handling
// NewSessionTicket messages. nil if config.SessionTicketsDisabled.
resumptionSecret []byte
// ticketKeys is the set of active session ticket keys for this
// connection. The first one is used to encrypt new tickets and
// all are tried to decrypt tickets.
ticketKeys []ticketKey
// clientFinishedIsFirst is true if the client sent the first Finished
// message during the most recent handshake. This is recorded because
// the first transmitted Finished message is the tls-unique
// channel-binding value.
clientFinishedIsFirst bool
// closeNotifyErr is any error from sending the alertCloseNotify record.
closeNotifyErr error
// closeNotifySent is true if the Conn attempted to send an
// alertCloseNotify record.
closeNotifySent bool
// clientFinished and serverFinished contain the Finished message sent
// by the client or server in the most recent handshake. This is
// retained to support the renegotiation extension and tls-unique
// channel-binding.
clientFinished [12]byte
serverFinished [12]byte
clientProtocol string
clientProtocolFallback bool
// input/output
in, out halfConn
rawInput bytes.Buffer // raw input, starting with a record header
input bytes.Reader // application data waiting to be read, from rawInput.Next
hand bytes.Buffer // handshake data waiting to be read
outBuf []byte // scratch buffer used by out.encrypt
buffering bool // whether records are buffered in sendBuf
sendBuf []byte // a buffer of records waiting to be sent
// bytesSent counts the bytes of application data sent.
// packetsSent counts packets.
bytesSent int64
packetsSent int64
// retryCount counts the number of consecutive non-advancing records
// received by Conn.readRecord. That is, records that neither advance the
// handshake, nor deliver application data. Protected by in.Mutex.
retryCount int
// activeCall is an atomic int32; the low bit is whether Close has
// been called. the rest of the bits are the number of goroutines
// in Conn.Write.
activeCall int32
tmp [16]byte
}
Conn代表一个安全连接。本类型实现了net.Conn接口。
func (*Conn) LocalAddr
func (c *Conn) LocalAddr() net.Addr
LocalAddr返回本地网络地址。
func (*Conn) RemoteAddr
func (c *Conn) RemoteAddr() net.Addr
LocalAddr返回远端网络地址。
func (*Conn) ConnectionState
func (c *Conn) ConnectionState() ConnectionState
ConnectionState返回该连接的基本TLS细节。
func (*Conn) SetDeadline
func (c *Conn) SetDeadline(t time.Time) error
SetDeadline设置该连接的读写操作绝对期限。t为Time零值表示不设置超时。在一次Write/Read方法超时后,TLS连接状态会被破坏,之后所有的读写操作都会返回同一错误。
func (*Conn) SetReadDeadline
func (c *Conn) SetReadDeadline(t time.Time) error
SetReadDeadline设置该连接的读操作绝对期限。t为Time零值表示不设置超时。
func (*Conn) SetWriteDeadline
func (c *Conn) SetWriteDeadline(t time.Time) error
SetReadDeadline设置该连接的写操作绝对期限。t为Time零值表示不设置超时。在一次Write方法超时后,TLS连接状态会被破坏,之后所有的写操作都会返回同一错误。
func (*Conn) Handshake
func (c *Conn) Handshake() error
Handshake执行客户端或服务端的握手协议(如果还没有执行的话)。本包的大多数应用不需要显式的调用Handsake方法:第一次Read或Write方法会自动调用本方法。
func (*Conn) VerifyHostname
func (c *Conn) VerifyHostname(host string) error
VerifyHostname检查用于连接到host的对等实体证书链是否合法。如果合法,它会返回nil;否则,会返回一个描述该问题的错误。
func (*Conn) OCSPResponse
func (c *Conn) OCSPResponse() []byte
OCSPResponse返回来自服务端的OCSP staple回复(如果有)。只有客户端可以使用本方法。
func (*Conn) Read
func (c *Conn) Read(b []byte) (n int, err error)
Read从连接读取数据,可设置超时,参见SetDeadline和SetReadDeadline。
func (*Conn) Write
func (c *Conn) Write(b []byte) (int, error)
Write将数据写入连接,可设置超时,参见SetDeadline和SetWriteDeadline。
func (*Conn) Close
func (c *Conn) Close() error
Close关闭连接。
func Client
func Client(conn net.Conn, config *Config) *Conn
Client使用conn作为下层传输接口返回一个TLS连接的客户端侧。配置参数config必须是非nil的且必须设置了ServerName或者InsecureSkipVerify字段。
func Server
func Server(conn net.Conn, config *Config) *Conn
Server使用conn作为下层传输接口返回一个TLS连接的服务端侧。配置参数config必须是非nil的且必须含有至少一个证书。
func Dial
func Dial(network, addr string, config *Config) (*Conn, error)
Dial使用net.Dial连接指定的网络和地址,然后发起TLS握手,返回生成的TLS连接。Dial会将nil的配置视为零值的配置;参见Config类型的文档获取细节。
func DialWithDialer
func DialWithDialer(dialer *net.Dialer, network, addr string, config *Config) (*Conn, error)
DialWithDialer使用dialer.Dial连接指定的网络和地址,然后发起TLS握手,返回生成的TLS连接。dialer中的超时和期限设置会将连接和TLS握手作为一个整体来应用。
DialWithDialer会将nil的配置视为零值的配置;参见Config类型的文档获取细节。
func Listen
func Listen(network, laddr string, config *Config) (net.Listener, error)
函数创建一个TLS监听器,使用net.Listen函数接收给定地址上的连接。配置参数config必须是非nil的且必须含有至少一个证书。
func NewListener
func NewListener(inner net.Listener, config *Config) net.Listener
函数创建一个TLS监听器,该监听器接受inner接收到的每一个连接,并调用Server函数包装这些连接。配置参数config必须是非nil的且必须含有至少一个证书。
有疑问加站长微信联系(非本文作者)