(hello *clientHelloMsg)
| 241 | } |
| 242 | |
| 243 | func (c *Conn) loadSession(hello *clientHelloMsg) (cacheKey string, |
| 244 | session *ClientSessionState, earlySecret, binderKey []byte) { |
| 245 | if c.config.SessionTicketsDisabled || c.config.ClientSessionCache == nil { |
| 246 | return "", nil, nil, nil |
| 247 | } |
| 248 | |
| 249 | hello.ticketSupported = true |
| 250 | |
| 251 | if hello.supportedVersions[0] == VersionTLS13 { |
| 252 | // Require DHE on resumption as it guarantees forward secrecy against |
| 253 | // compromise of the session ticket key. See RFC 8446, Section 4.2.9. |
| 254 | hello.pskModes = []uint8{pskModeDHE} |
| 255 | } |
| 256 | |
| 257 | // Session resumption is not allowed if renegotiating because |
| 258 | // renegotiation is primarily used to allow a client to send a client |
| 259 | // certificate, which would be skipped if session resumption occurred. |
| 260 | if c.handshakes != 0 { |
| 261 | return "", nil, nil, nil |
| 262 | } |
| 263 | |
| 264 | // Try to resume a previously negotiated TLS session, if available. |
| 265 | cacheKey = clientSessionCacheKey(c.conn.RemoteAddr(), c.config) |
| 266 | session, ok := c.config.ClientSessionCache.Get(cacheKey) |
| 267 | if !ok || session == nil { |
| 268 | return cacheKey, nil, nil, nil |
| 269 | } |
| 270 | |
| 271 | // Check that version used for the previous session is still valid. |
| 272 | versOk := false |
| 273 | for _, v := range hello.supportedVersions { |
| 274 | if v == session.vers { |
| 275 | versOk = true |
| 276 | break |
| 277 | } |
| 278 | } |
| 279 | if !versOk { |
| 280 | return cacheKey, nil, nil, nil |
| 281 | } |
| 282 | |
| 283 | // Check that the cached server certificate is not expired, and that it's |
| 284 | // valid for the ServerName. This should be ensured by the cache key, but |
| 285 | // protect the application from a faulty ClientSessionCache implementation. |
| 286 | if !c.config.InsecureSkipVerify { |
| 287 | if len(session.verifiedChains) == 0 { |
| 288 | // The original connection had InsecureSkipVerify, while this doesn't. |
| 289 | return cacheKey, nil, nil, nil |
| 290 | } |
| 291 | serverCert := session.serverCertificates[0] |
| 292 | if c.config.time().After(serverCert.NotAfter) { |
| 293 | // Expired certificate, delete the entry. |
| 294 | c.config.ClientSessionCache.Put(cacheKey, nil) |
| 295 | return cacheKey, nil, nil, nil |
| 296 | } |
| 297 | if err := serverCert.VerifyHostname(c.config.ServerName); err != nil { |
| 298 | return cacheKey, nil, nil, nil |
| 299 | } |
| 300 | } |
no test coverage detected