import "crypto/tls"
tls包实现了TLS 1.2,细节参见RFC 5246。
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 int
ClientAuthType类型声明服务端将遵循的TLS客户端验证策略。
const ( NoClientCert ClientAuthType = iota RequestClientCert RequireAnyClientCert VerifyClientCertIfGiven RequireAndVerifyClientCert )
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 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(certFile, keyFile string) (cert Certificate, err error)
LoadX509KeyPair读取并解析一对文件获取公钥和私钥。这些文件必须是PEM编码的。
func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (cert Certificate, err error)
X509KeyPair解析一对PEM编码的数据获取公钥和私钥。
type ClientSessionState struct {
// 内含隐藏或非导出字段
}
ClientSessionState包含客户端所需的用于恢复TLS会话的状态。
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(capacity int) ClientSessionCache
函数使用给出的容量创建一个采用LRU策略的ClientSessionState,如果capacity<1会采用默认容量。
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 (c *Config) BuildNameToCertificate()
BuildNameToCertificate解析c.Certificates并将每一个叶证书的CommonName和SubjectAlternateName字段用于创建c.NameToCertificate。
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 struct {
// 内含隐藏或非导出字段
}
Conn代表一个安全连接。本类型实现了net.Conn接口。
func (c *Conn) LocalAddr() net.Addr
LocalAddr返回本地网络地址。
func (c *Conn) RemoteAddr() net.Addr
LocalAddr返回远端网络地址。
func (c *Conn) ConnectionState() ConnectionState
ConnectionState返回该连接的基本TLS细节。
func (c *Conn) SetDeadline(t time.Time) error
SetDeadline设置该连接的读写操作绝对期限。t为Time零值表示不设置超时。在一次Write/Read方法超时后,TLS连接状态会被破坏,之后所有的读写操作都会返回同一错误。
func (c *Conn) SetReadDeadline(t time.Time) error
SetReadDeadline设置该连接的读操作绝对期限。t为Time零值表示不设置超时。
func (c *Conn) SetWriteDeadline(t time.Time) error
SetReadDeadline设置该连接的写操作绝对期限。t为Time零值表示不设置超时。在一次Write方法超时后,TLS连接状态会被破坏,之后所有的写操作都会返回同一错误。
func (c *Conn) Handshake() error
Handshake执行客户端或服务端的握手协议(如果还没有执行的话)。本包的大多数应用不需要显式的调用Handsake方法:第一次Read或Write方法会自动调用本方法。
func (c *Conn) VerifyHostname(host string) error
VerifyHostname检查用于连接到host的对等实体证书链是否合法。如果合法,它会返回nil;否则,会返回一个描述该问题的错误。
func (c *Conn) OCSPResponse() []byte
OCSPResponse返回来自服务端的OCSP staple回复(如果有)。只有客户端可以使用本方法。
func (c *Conn) Read(b []byte) (n int, err error)
Read从连接读取数据,可设置超时,参见SetDeadline和SetReadDeadline。
func (c *Conn) Write(b []byte) (int, error)
Write将数据写入连接,可设置超时,参见SetDeadline和SetWriteDeadline。
func (c *Conn) Close() error
Close关闭连接。
func Client(conn net.Conn, config *Config) *Conn
Client使用conn作为下层传输接口返回一个TLS连接的客户端侧。配置参数config必须是非nil的且必须设置了ServerName或者InsecureSkipVerify字段。
func Server(conn net.Conn, config *Config) *Conn
Server使用conn作为下层传输接口返回一个TLS连接的服务端侧。配置参数config必须是非nil的且必须含有至少一个证书。
func Dial(network, addr string, config *Config) (*Conn, error)
Dial使用net.Dial连接指定的网络和地址,然后发起TLS握手,返回生成的TLS连接。Dial会将nil的配置视为零值的配置;参见Config类型的文档获取细节。
// Connecting with a custom root-certificate set. const rootPEM = ` -----BEGIN CERTIFICATE----- MIIEBDCCAuygAwIBAgIDAjppMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i YWwgQ0EwHhcNMTMwNDA1MTUxNTU1WhcNMTUwNDA0MTUxNTU1WjBJMQswCQYDVQQG EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB+zCB+DAfBgNVHSMEGDAWgBTAephojYn7 qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wEgYD VR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMwMTAvoC2g K4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9ndGdsb2JhbC5jcmwwPQYI KwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwOi8vZ3RnbG9iYWwtb2NzcC5n ZW90cnVzdC5jb20wFwYDVR0gBBAwDjAMBgorBgEEAdZ5AgUBMA0GCSqGSIb3DQEB BQUAA4IBAQA21waAESetKhSbOHezI6B1WLuxfoNCunLaHtiONgaX4PCVOzf9G0JY /iLIa704XtE7JW4S615ndkZAkNoUyHgN7ZVm2o6Gb4ChulYylYbc3GrKBIxbf/a/ zG+FA1jDaFETzf3I93k9mTXwVqO94FntT0QJo544evZG0R0SnU++0ED8Vf4GXjza HFa9llF7b1cq26KqltyMdMKVvvBulRP/F/A8rLIQjcxz++iPAsbw+zOzlTvjwsto WHPbqCRiOwY1nQ2pM714A5AuTHhdUDqB1O6gyHA43LL5Z/qHQF1hwFGPa4NrzQU6 yuGnBXj8ytqU0CwIPX4WecigUCAkVDNx -----END CERTIFICATE-----` // First, create the set of root certificates. For this example we only // have one. It's also possible to omit this in order to use the // default root set of the current operating system. roots := x509.NewCertPool() ok := roots.AppendCertsFromPEM([]byte(rootPEM)) if !ok { panic("failed to parse root certificate") } conn, err := tls.Dial("tcp", "mail.google.com:443", &tls.Config{ RootCAs: roots, }) if err != nil { panic("failed to connect: " + err.Error()) } conn.Close()
func DialWithDialer(dialer *net.Dialer, network, addr string, config *Config) (*Conn, error)
DialWithDialer使用dialer.Dial连接指定的网络和地址,然后发起TLS握手,返回生成的TLS连接。dialer中的超时和期限设置会将连接和TLS握手作为一个整体来应用。
DialWithDialer会将nil的配置视为零值的配置;参见Config类型的文档获取细节。
func Listen(network, laddr string, config *Config) (net.Listener, error)
函数创建一个TLS监听器,使用net.Listen函数接收给定地址上的连接。配置参数config必须是非nil的且必须含有至少一个证书。
func NewListener(inner net.Listener, config *Config) net.Listener
函数创建一个TLS监听器,该监听器接受inner接收到的每一个连接,并调用Server函数包装这些连接。配置参数config必须是非nil的且必须含有至少一个证书。