?
本文檔使用 php中文網(wǎng)手冊 發(fā)布
import "crypto/tls"
概述
索引
示例
按照RFC 5246 的規(guī)定,軟件包部分實現(xiàn)了 TLS 1.2。
Constants
func Listen(network, laddr string, config *Config) (net.Listener, error)
func NewListener(inner net.Listener, config *Config) net.Listener
type Certificate
func LoadX509KeyPair(certFile, keyFile string) (Certificate, error)
func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (Certificate, error)
type CertificateRequestInfo
type ClientAuthType
type ClientHelloInfo
type ClientSessionCache
func NewLRUClientSessionCache(capacity int) ClientSessionCache
type ClientSessionState
type Config
func (c *Config) BuildNameToCertificate()
func (c *Config) Clone() *Config
func (c *Config) SetSessionTicketKeys(keys [][32]byte)
type Conn
func Client(conn net.Conn, config *Config) *Conn
func Dial(network, addr string, config *Config) (*Conn, error)
func DialWithDialer(dialer *net.Dialer, network, addr string, config *Config) (*Conn, error)
func Server(conn net.Conn, config *Config) *Conn
func (c *Conn) Close() error
func (c *Conn) CloseWrite() error
func (c *Conn) ConnectionState() ConnectionState
func (c *Conn) Handshake() error
func (c *Conn) LocalAddr() net.Addr
func (c *Conn) OCSPResponse() []byte
func (c *Conn) Read(b []byte) (n int, err error)
func (c *Conn) RemoteAddr() net.Addr
func (c *Conn) SetDeadline(t time.Time) error
func (c *Conn) SetReadDeadline(t time.Time) error
func (c *Conn) SetWriteDeadline(t time.Time) error
func (c *Conn) VerifyHostname(host string) error
func (c *Conn) Write(b []byte) (int, error)
type ConnectionState
type CurveID
type RecordHeaderError
func (e RecordHeaderError) Error() string
type RenegotiationSupport
type SignatureScheme
Bugs
Config (KeyLogWriter) Dial
alert.go cipher_suites.go common.go conn.go handshake_client.go handshake_messages.go handshake_server.go key_agreement.go prf.go ticket.go tls.go
此軟件包已實施或已經(jīng)實施的密碼套件 ID 列表。
取自http://www.iana.org/assignments/tls-parameters/tls-parameters.xml
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_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x003c TLS_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x009c TLS_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x009d 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_ECDSA_WITH_AES_128_CBC_SHA256 uint16 = 0xc023 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0xc027 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02f TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02b TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc030 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc02c TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 uint16 = 0xcca8 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 uint16 = 0xcca9 // TLS_FALLBACK_SCSV不是標準密碼套件,而是指標 // 客戶端正在進行版本回退。 參見 // https://tools.ietf.org/html/rfc7507。 TLS_FALLBACK_SCSV uint16 = 0x5600)
const ( VersionSSL30 = 0x0300 VersionTLS10 = 0x0301 VersionTLS11 = 0x0302 VersionTLS12 = 0x0303)
func Listen(network, laddr string, config *Config) (net.Listener, error)
Listen 會使用 net.Listen 創(chuàng)建一個 TLS 偵聽器來接受給定網(wǎng)絡(luò)地址上的連接。配置配置必須非零,并且必須包含至少一個證書或者設(shè)置 GetCertificate。
func NewListener(inner net.Listener, config *Config) net.Listener
NewListener創(chuàng)建一個 Listener,它接受來自內(nèi)部 Listener 的連接并將每個連接包裝在 Server 中。配置必須非零,并且必須包含至少一個證書或者設(shè)置 GetCertificate。
證書是一個或多個證書的鏈,首先是 leaf。
type Certificate struct { Certificate [][]byte // PrivateKey包含與公鑰對應的私鑰 // 在Leaf中。 對于服務(wù)器,這必須實現(xiàn) // crypto.Decrypter,帶有RSA或ECDSA // (執(zhí)行客戶端身份驗證),這必須是 // 使用RSA或ECDSA PublicKey。 PrivateKey crypto.PrivateKey // OCSPStaple包含一個可選的OCSP響應 // 給要求它的客戶端。 OCSPStaple []byte // SignedCertificateTimestamps包含一個可選的Signed列表 // 證書時間戳將提供給請求它的客戶端。 SignedCertificateTimestamps [][]byte // Leaf是葉證書的解析形式,可能是 // 使用x509.ParseCertificate初始化以減少per-handshaking(每次握手) // 處理進行客戶端身份驗證的TLS客戶端。 如果沒有,那么 // leaf證書將根據(jù)需要進行解析。 Leaf *x509.Certificate}
func LoadX509KeyPair(certFile, keyFile string) (Certificate, error)
LoadX509KeyPair 讀取并解析來自一對文件的公鑰/私鑰對。這些文件必須包含 PEM 編碼數(shù)據(jù)。證書文件可能包含 leaf 證書之后的中間證書以形成證書鏈。成功返回時,Certificate.Leaf 將為零,因為不會保留解析的證書形式。
func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (Certificate, error)
X509KeyPair 從一對 PEM 編碼數(shù)據(jù)中解析公鑰/私鑰對。成功返回時,Certificate.Leaf 將為零,因為不會保留解析的證書形式。
CertificateRequestInfo 包含來自服務(wù)器的 CertificateRequest 消息的信息,該消息用于請求客戶端的證書和控制證明。
type CertificateRequestInfo struct { // AcceptableCAs包含零個或多個DER編碼的X.501 // 杰出的名稱(Names)。 這些是根CA或中間CA的名稱 // 服務(wù)器希望返回的證書由簽名。 一個 // 空切片表示服務(wù)器沒有首選項。 AcceptableCAs [][]byte // SignatureSchemes列出了服務(wù)器的簽名方案 // 愿意核實。 SignatureSchemes []SignatureScheme}
ClientAuthType 聲明服務(wù)器將遵循 TLS 客戶端身份驗證的策略。
type ClientAuthType int
const ( NoClientCert ClientAuthType = iota RequestClientCert RequireAnyClientCert VerifyClientCertIfGiven RequireAndVerifyClientCert)
ClientHelloInfo 包含來自 ClientHello 消息的信息,以指導 GetCertificate 回調(diào)中的證書選擇。
type ClientHelloInfo struct { // CipherSuites列出了客戶端支持的CipherSuite(例如 // TLS_RSA_WITH_RC4_128_SHA)。 CipherSuites []uint16 // ServerName表示客戶端請求的服務(wù)器的名稱 // 為了支持虛擬主機。 ServerName僅在設(shè)置時設(shè)置 // 客戶端正在使用SNI(參見 // http://tools.ietf.org/html/rfc4366#section-3.1)。 ServerName string // SupportedCurves列出客戶端支持的橢圓曲線。 // 僅當支持的橢圓曲線時,才設(shè)置SupportedCurves // 正在使用擴展(參見 // http://tools.ietf.org/html/rfc4492#section-5.1.1)。 SupportedCurves []CurveID // SupportedPoints列出了客戶端支持的點格式。 // 僅當支持的點格式擴展時才設(shè)置SupportedPoints // 正在使用(參見 // http://tools.ietf.org/html/rfc4492#section-5.1.2)。 SupportedPoints []uint8 // SignatureSchemes列出了客戶端的簽名和哈希方案 // 愿意驗證。 SignatureSchemes僅在簽名時設(shè)置 // 正在使用算法擴展(參見 // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1)。 SignatureSchemes []SignatureScheme // SupportedProtos列出客戶端支持的應用程序協(xié)議。 // 僅在應用程序?qū)訁f(xié)議時設(shè)置SupportedProtos // 正在使用談判擴展(參見 // https://tools.ietf.org/html/rfc7301#section-3.1)。 // // 服務(wù)器可以通過在以下設(shè)置Config.NextProtos來選擇協(xié)議 // GetConfigForClient返回值。 SupportedProtos []string // SupportedVersions列出客戶端支持的TLS版本。 // 對于小于1.3的TLS版本,這是從最大值推斷出來的 // 客戶端廣告的版本,所以除最大值之外的其他值 // 如果使用可能會被拒絕。 SupportedVersions []uint16 // Conn是連接的基礎(chǔ)net.Conn。 匆讀 // 來自或?qū)懭氪诉B接; 這將導致TLS // 連接失敗。 Conn net.Conn}
ClientSessionCache 是 ClientSessionState 對象的緩存,可由客戶端用來恢復與給定服務(wù)器的 TLS 會話。ClientSessionCache 實現(xiàn)應該期望從不同的 goroutine 同時調(diào)用。只支持基于票據(jù)的恢復,不支持基于 SessionID 的恢復。
type ClientSessionCache interface { // 獲取與給定密鑰關(guān)聯(lián)的ClientSessionState的搜索。 // 返回時,如果找到一個,則確定。 Get(sessionKey string) (session *ClientSessionState, ok bool) // Put使用給定鍵將ClientSessionState添加到緩存中。 Put(sessionKey string, cs *ClientSessionState)}
func NewLRUClientSessionCache(capacity int) ClientSessionCache
NewLRUClientSessionCache 返回一個具有使用 LRU 策略的給定容量的 ClientSessionCache。如果容量<1,則使用默認容量。
ClientSessionState 包含客戶端恢復 TLS 會話所需的狀態(tài)。
type ClientSessionState struct { // 包含已過濾或未導出的字段}
配置結(jié)構(gòu)用于配置 TLS 客戶端或服務(wù)器。在傳遞給 TLS 函數(shù)之后,它不能被修改。配置可能會被重用; tls 包也不會修改。
type Config struct { // Rand為nonce和RSA致盲提供了熵的來源。 // 如果Rand為零,則TLS在包中使用加密隨機讀取器 // crypto/rand。 // 閱讀器必須安全使用多個goroutines。 Rand io.Reader // 時間將當前時間作為自紀元以來的秒數(shù)返回。 // 如果Time為nil,則TLS使用time.Now。 Time func() time.Time // 證書包含一個或多個要呈現(xiàn)的證書鏈 // 連接的另一面。 服務(wù)器配置必須包含 // 至少一個證書或設(shè)置GetCertificate。 客戶端正在 // 客戶端身份驗證可以設(shè)置證書或 // GetClientCertificate。 Certificates []Certificate // NameToCertificate從證書名稱映射到元素 // 證書。 請注意,證書名稱可以是表單 // '* .example.com'因此不必是域名。 // 請參見Config.BuildNameToCertificate // nil值導致使用證書的第一個元素 // 對于所有連接。 NameToCertificate map[string]*Certificate // GetCertificate根據(jù)給定的值返回證書 // ClientHelloInfo。 只有在客戶提供SNI時才會調(diào)用 // 信息或證書是否為空。 // // 如果GetCertificate為nil或返回nil,則證書為 // 從NameToCertificate檢索。 如果NameToCertificate是nil,那么 // 將使用證書的第一個元素。 GetCertificate func(*ClientHelloInfo) (*Certificate, error) // GetClientCertificate,如果不是nil,則在服務(wù)器請求時調(diào)用 // 來自客戶的證書。 如果設(shè)置,證書的內(nèi)容將 // 被忽略。 // // 如果GetClientCertificate返回錯誤,則握手(handshake)將是 // 中止,將返回該錯誤。 除此以外 // GetClientCertificate必須返回非零證書。 如果 // Certificate.Certificate為空,則不會發(fā)送任何證書 // 服務(wù)器。 如果這對服務(wù)器來說是不可接受的,那么它可能會中止 // 握手。 // // 可以多次調(diào)用GetClientCertificate // 如果發(fā)生重新協(xié)商或者正在使用TLS 1.3,則連接。 GetClientCertificate func(*CertificateRequestInfo) (*Certificate, error) // GetConfigForClient,如果不是nil,則在ClientHello之后調(diào)用 // 從客戶端那里收到 它可能會返回一個非零配置 // 更改將用于處理此連接的Config。 如果 // 返回的Config為nil,將使用原始配置。該 // 此回調(diào)返回的配置可能不會隨后被修改。 // // 如果GetConfigForClient為nil,則傳遞給Server()的Config將為 // 用于所有連接。 // // 對于返回的Config中的字段,會話票證密鑰是唯一的 // 如果未設(shè)置,將從原始配置中復制。 // 具體來說,如果在原始上調(diào)用了SetSessionTicketKeys // 配置但不在返回的配置上,然后從票證鍵 // 原始配置將在使用前復制到新配置中。 // 否則,如果在原始配置中設(shè)置了SessionTicketKey但是 // 不在返回的配置中然后它將被復制到返回的 // 使用前配置。 如果這兩種情況都不適用那么關(guān)鍵 // 返回的配置中的材料將用于會話票證。 GetConfigForClient func(*ClientHelloInfo) (*Config, error) // VerifyPeerCertificate,如果不是nil,則在正常情況下被調(diào)用 // 由TLS客戶端或服務(wù)器驗證證書。 它 // 接收對等方提供的原始ASN.1證書 // 正常處理發(fā)現(xiàn)的任何經(jīng)過驗證的鏈。 如果它返回一個 // 非零錯誤,中止握手并產(chǎn)生錯誤。 // // 如果正常驗證失敗,那么握手將在之前中止 // 考慮這個回調(diào)。 如果禁用正常驗證 // 設(shè)置InsecureSkipVerify然后會考慮這個回調(diào)但是 // verifiedChains參數(shù)將始終為零。 VerifyPeerCertificate func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error // RootCAs定義了根證書授權(quán)的集合 // 客戶端在驗證服務(wù)器證書時使用。 // 如果RootCAs為nil,則TLS使用主機的根CA集。 RootCAs *x509.CertPool // NextProtos是受支持的應用程序級協(xié)議列表。 NextProtos []string // ServerName用于驗證返回的主機名 // 證書,除非給出InsecureSkipVerify。 它也包括在內(nèi) // 在客戶端的握手中支持虛擬主機,除非它是 // 一個IP地址。 ServerName string // ClientAuth確定服務(wù)器的策略 // TLS客戶端身份驗證。 默認值為NoClientCert。 ClientAuth ClientAuthType // ClientCAs定義了根證書頒發(fā)機構(gòu)的集合 // 服務(wù)器使用,如果需要驗證客戶端證書 // 通過ClientAuth中的策略。 ClientCAs *x509.CertPool // InsecureSkipVerify控制客戶端是否驗證 // 服務(wù)器的證書鏈和主機名。 // 如果InsecureSkipVerify為true,則TLS接受任何證書 // 由服務(wù)器和該證書中的任何主機名提供。 // 在這種模式下,TLS容易受到man-in-the-middle攻擊。 // 這應該僅用于測試。 InsecureSkipVerify bool // CipherSuites是受支持的密碼套件列表。 如果是CipherSuites // 是零,TLS使用實現(xiàn)支持的套件列表。 CipherSuites []uint16 // PreferServerCipherSuites控制服務(wù)器是否選擇 // 客戶端最喜歡的密碼套件,或服務(wù)器最優(yōu)選的密碼套件 // 密碼套件。 如果為true則為服務(wù)器的首選項,如表所示 // 使用CipherSuites中元素的順序。 PreferServerCipherSuites bool // 可以將SessionTicketsDisabled設(shè)置為true以禁用會話票證 // (恢復)支持。 SessionTicketsDisabled bool // TLS服務(wù)器使用SessionTicketKey來提供會話 // 恢復。 請參閱RFC 5077.如果為零,則將填充 // 第一次服務(wù)器握手之前的隨機數(shù)據(jù)。 // // 如果多個服務(wù)器正在終止同一主機的連接 // 他們都應該擁有相同的SessionTicketKey。 如果 // SessionTicketKey泄漏,以前記錄和未來的TLS // 使用該密鑰的連接受到損害。 SessionTicketKey [32]byte // SessionCache是TLS會話的ClientSessionState條目的緩存 // 恢復。 ClientSessionCache ClientSessionCache // MinVersion包含可接受的最小SSL/TLS版本。 // 如果為零,則將TLS 1.0作為最小值。 MinVersion uint16 // MaxVersion包含可接受的最大SSL/TLS版本。 // 如果為零,則使用此程序包支持的最大版本, // 目前是TLS 1.2。 MaxVersion uint16 // CurvePreferences包含將在其中使用的橢圓曲線 // ECDHE握手,按優(yōu)先順序排列。 如果為空,則默認為 // 被使用。 CurvePreferences []CurveID // DynamicRecordSizingDisabled禁用TLS記錄的自適應大小調(diào)整。 // 如果為true,則始終使用最大可能的TLS記錄大小。 當 // false時,可以調(diào)整TLS記錄的大小 // 改善延遲。 DynamicRecordSizingDisabled bool // 重新協(xié)商控制支持哪種類型的重新協(xié)商。 // 對于絕大多數(shù)應用程序,默認值none都是正確的。 Renegotiation RenegotiationSupport // KeyLogWriter可選擇指定TLS主機密的目標 // 在NSS密鑰日志格式中,可用于允許外部程序 // 比如Wireshark來解密TLS連接。 // 請參閱https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format。 // 使用KeyLogWriter會危及安全性,應該只是 // 用于調(diào)試。 KeyLogWriter io.Writer // 包含已過濾或未導出的字段}
代碼:
// 通過解密網(wǎng)絡(luò)流量捕獲來調(diào)試TLS應用程序。// 警告:使用KeyLogWriter會危及安全性,并且應該只是// 用于調(diào)試。// 虛假測試HTTP服務(wù)器的示例具有不安全的隨機輸出// 重復性。server := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}))server.TLS = &tls.Config{ Rand: zeroSource{}, // 僅舉例來說; 不要這樣做。}server.StartTLS()defer server.Close()// 通常,日志將轉(zhuǎn)到打開的文件:// w, err := os.OpenFile("tls-secrets.txt", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)w := os.Stdout client := &http.Client{ Transport: &http.Transport{ TLSClientConfig: &tls.Config{ KeyLogWriter: w, Rand: zeroSource{}, // 用于可重復的輸出; 不要這樣做。 InsecureSkipVerify: true, // 測試服務(wù)器證書不受信任。 }, },}resp, err := client.Get(server.URL)if err != nil { log.Fatalf("Failed to get URL: %v", err)}resp.Body.Close()// 生成的文件可以與Wireshark一起使用來解密TLS// 通過在SSL協(xié)議中設(shè)置(Pre)-Master-Secret日志文件名來連接// 優(yōu)先級。
輸出:
CLIENT_RANDOM 0000000000000000000000000000000000000000000000000000000000000000 baca0df460a688e44ce018b025183cc2353ae01f89755ef766eedd3ecc302888ee3b3a22962e45f48c20df15a98c0e80
func (c *Config) BuildNameToCertificate()
BuildNameToCertificate 解析 c.Certificates 并從每個 leaf 證書的 CommonName 和 SubjectAlternateName 字段構(gòu)建 c.NameToCertificate。
func (c *Config) Clone() *Config
Clone 返回c的淺層 clone??寺?TLS 客戶端或服務(wù)器正在同時使用的配置是安全的。
func (c *Config) SetSessionTicketKeys(keys [][32]byte)
SetSessionTicketKeys 更新服務(wù)器的會話票證密鑰。創(chuàng)建新票時將使用第一個鍵,而所有鍵都可用于解密票。在服務(wù)器運行時調(diào)用此函數(shù)以便旋轉(zhuǎn)會話票據(jù)密鑰是安全的。如果鍵為空,該功能將會出現(xiàn)混亂。
Conn 代表安全連接。它實現(xiàn)了 net.Conn 接口。
type Conn struct { // 包含已過濾或未導出的字段}
func Client(conn net.Conn, config *Config) *Conn
客戶端使用 conn 作為底層傳輸返回新的 TLS 客戶端連接。配置不能為零:用戶必須在配置中設(shè)置 ServerName 或 InsecureSkipVerify。
func Dial(network, addr string, config *Config) (*Conn, error)
撥號使用 net.Dial 連接到給定的網(wǎng)絡(luò)地址,然后啟動 TLS handshake,返回生成的 TLS 連接。撥號將零配置解釋為等同于零配置;請參閱 Config 的文檔以了解默認值。
package mainimport ("crypto/tls""crypto/x509")func main() {// 使用自定義根證書集連接。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-----`// 首先,創(chuàng)建一組根證書。 對于這個例子我們只// 有一個。 也可以省略這個以便使用// 當前操作系統(tǒng)的默認根集。 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 連接到給定的網(wǎng)絡(luò)地址,然后啟動TLS handshake,返回生成的 TLS 連接。撥號程序中給出的任何超時或截止日期都適用于連接和 TLS handshake。
DialWithDialer 將零配置解釋為等同于零配置;請參閱 Config 的文檔以了解默認值。
func Server(conn net.Conn, config *Config) *Conn
服務(wù)器返回一個新的 TLS 服務(wù)器端連接,使用 conn 作為底層傳輸。配置配置必須非零,并且必須包含至少一個證書或者設(shè)置 GetCertificate。
func (c *Conn) Close() error
Close 關(guān)閉連接。
func (c *Conn) CloseWrite() error
CloseWrite 關(guān)閉連接的寫入側(cè)。只有在 handshake 完成后才能調(diào)用,并且不會在基礎(chǔ)連接上調(diào)用 CloseWrite。大多數(shù)調(diào)用者應該只使用關(guān)閉。
func (c *Conn) ConnectionState() ConnectionState
ConnectionState 返回有關(guān)連接的基本 TLS 詳細信息。
func (c *Conn) Handshake() error
如果尚未運行,handshake 會運行客戶端或服務(wù)器 handshake 協(xié)議。這個包的大部分使用都不需要明確調(diào)用 Handshake:第一個Read 或 Write 會自動調(diào)用。
func (c *Conn) LocalAddr() net.Addr
LocalAddr 返回本地網(wǎng)絡(luò)地址。
func (c *Conn) OCSPResponse() []byte
OCSPResponse 返回來自 TLS 服務(wù)器的已裝訂的 OCSP 響應(如果有)。(僅對客戶端連接有效。)
func (c *Conn) Read(b []byte) (n int, err error)
可以使讀超時并返回一個 net.Error Timeout()== true 在一個固定的時間限制后; 請參閱 SetDeadline 和 SetReadDeadline。
func (c *Conn) RemoteAddr() net.Addr
RemoteAddr 返回遠程網(wǎng)絡(luò)地址。
func (c *Conn) SetDeadline(t time.Time) error
SetDeadline 設(shè)置與連接關(guān)聯(lián)的讀取和寫入最后期限。t 表示讀取和寫入不會超時。寫入超時后,TLS 狀態(tài)已損壞,所有將來的寫入都將返回相同的錯誤。
func (c *Conn) SetReadDeadline(t time.Time) error
SetReadDeadline 設(shè)置底層連接的讀取最后期限。t 代表零值表示Read 不會超時。
func (c *Conn) SetWriteDeadline(t time.Time) error
SetWriteDeadline 設(shè)置底層連接的寫入截止時間。t 的零值意味著Write 不會超時。寫入超時后,TLS 狀態(tài)已損壞,所有將來的寫入都將返回相同的錯誤。
func (c *Conn) VerifyHostname(host string) error
VerifyHostname 檢查對等證書鏈對于連接到主機是否有效。如果是,則返回零;如果不是,則返回描述問題的錯誤。
func (c *Conn) Write(b []byte) (int, error)
Write 將數(shù)據(jù)寫入連接。
ConnectionState 記錄有關(guān)連接的基本 TLS 詳細信息。
type ConnectionState struct { Version uint16 // 連接使用的TLS版本(例如VersionTLS12) HandshakeComplete bool // TLS握手完成 DidResume bool // 連接恢復以前的TLS連接 CipherSuite uint16 // 正在使用的密碼套件(TLS_RSA_WITH_RC4_128_SHA,...) NegotiatedProtocol string // 協(xié)商下一個協(xié)議(不保證來自Config.NextProtos) NegotiatedProtocolIsMutual bool // 協(xié)商協(xié)議由服務(wù)器公布(僅限客戶端) ServerName string // 客戶端請求的服務(wù)器名稱(如果有)(僅限服務(wù)器端) PeerCertificates []*x509.Certificate // 遠程同行提供的證書鏈 VerifiedChains [][]*x509.Certificate // 經(jīng)過驗證的PeerCertificates鏈 SignedCertificateTimestamps [][]byte // 來自服務(wù)器的SCT,如果有的話 OCSPResponse []byte // 來自服務(wù)器的裝訂OCSP響應(如果有) // TLSUnique包含“tls-unique”通道綁定值(請參閱RFC // 5929,第3節(jié))。 對于恢復的會話,此值將為零 // 因為恢復不包括足夠的背景(參見 // https://mitls.org/pages/attacks/3SHAKE#channelbindings)。 // 一旦TLS主秘密修復具有,將在Go的未來版本中進行更改 // 已經(jīng)標準化和實施。 TLSUnique []byte}
CurveID 是橢圓曲線的 TLS 標識符的類型。請參閱http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-8
type CurveID uint16
const ( CurveP256 CurveID = 23 CurveP384 CurveID = 24 CurveP521 CurveID = 25 X25519 CurveID = 29)
當TLS記錄標題無效時,RecordHeaderError 產(chǎn)生結(jié)果。
type RecordHeaderError struct { // Msg包含描述錯誤的人類可讀字符串。 Msg string // RecordHeader包含五個字節(jié)的TLS記錄頭 // 觸發(fā)了錯誤。 RecordHeader [5]byte}
func (e RecordHeaderError) Error() string
重新協(xié)商支持列舉了 TLS 重新協(xié)商的不同級別的支持。TLS 重新協(xié)商是在第一次連接之后對連接執(zhí)行后續(xù)握手的行為。這使狀態(tài)機非常復雜,并且成為眾多細微安全問題的根源。不支持啟動重新協(xié)商,但可以啟用對接受重新協(xié)商請求的支持。
即使啟用,服務(wù)器也不能在握手之間更改其身份(即葉證書必須相同)。此外,不允許同時握手和應用程序數(shù)據(jù)流,因此重新協(xié)商只能用于與重新協(xié)商同步的協(xié)議,例如 HTTPS。
type RenegotiationSupport int
const ( // RenegotiateNever禁用重新協(xié)商。 RenegotiateNever RenegotiationSupport = iota // RenegotiateOnceAsClient允許遠程服務(wù)器請求 // 每次連接重新協(xié)商一次。 RenegotiateOnceAsClient // RenegotiateFreelyAsClient允許重復使用遠程服務(wù)器 // 請求重新談判。 RenegotiateFreelyAsClient)
SignatureScheme 標識TLS支持的簽名算法。請參閱https://tools.ietf.org/html/draft-ietf-tls-tls13-18#section-4.2.3。
type SignatureScheme uint16
const ( PKCS1WithSHA1 SignatureScheme = 0x0201 PKCS1WithSHA256 SignatureScheme = 0x0401 PKCS1WithSHA384 SignatureScheme = 0x0501 PKCS1WithSHA512 SignatureScheme = 0x0601 PSSWithSHA256 SignatureScheme = 0x0804 PSSWithSHA384 SignatureScheme = 0x0805 PSSWithSHA512 SignatureScheme = 0x0806 ECDSAWithP256AndSHA256 SignatureScheme = 0x0403 ECDSAWithP384AndSHA384 SignatureScheme = 0x0503 ECDSAWithP521AndSHA512 SignatureScheme = 0x0603)
? crypto/tls包只針對實現(xiàn)對CBC模式加密Lucky13攻擊的對策,只有對SHA1變種。見http://www.isg.rhul.ac.uk/tls/TLStiming.pdf和https://www.imperialviolet.org/2013/02/04/luckythirteen.html。