()
| 223 | } |
| 224 | |
| 225 | func (hs *serverHandshakeStateTLS13) checkForResumption() error { |
| 226 | c := hs.c |
| 227 | |
| 228 | if c.config.SessionTicketsDisabled { |
| 229 | return nil |
| 230 | } |
| 231 | |
| 232 | modeOK := false |
| 233 | for _, mode := range hs.clientHello.pskModes { |
| 234 | if mode == pskModeDHE { |
| 235 | modeOK = true |
| 236 | break |
| 237 | } |
| 238 | } |
| 239 | if !modeOK { |
| 240 | return nil |
| 241 | } |
| 242 | |
| 243 | if len(hs.clientHello.pskIdentities) != len(hs.clientHello.pskBinders) { |
| 244 | c.sendAlert(alertIllegalParameter) |
| 245 | return errors.New("tls: invalid or missing PSK binders") |
| 246 | } |
| 247 | if len(hs.clientHello.pskIdentities) == 0 { |
| 248 | return nil |
| 249 | } |
| 250 | |
| 251 | for i, identity := range hs.clientHello.pskIdentities { |
| 252 | if i >= maxClientPSKIdentities { |
| 253 | break |
| 254 | } |
| 255 | |
| 256 | plaintext, _ := c.decryptTicket(identity.label) |
| 257 | if plaintext == nil { |
| 258 | continue |
| 259 | } |
| 260 | sessionState := new(sessionStateTLS13) |
| 261 | if ok := sessionState.unmarshal(plaintext); !ok { |
| 262 | continue |
| 263 | } |
| 264 | |
| 265 | createdAt := time.Unix(int64(sessionState.createdAt), 0) |
| 266 | if c.config.time().Sub(createdAt) > maxSessionTicketLifetime { |
| 267 | continue |
| 268 | } |
| 269 | |
| 270 | // We don't check the obfuscated ticket age because it's affected by |
| 271 | // clock skew and it's only a freshness signal useful for shrinking the |
| 272 | // window for replay attacks, which don't affect us as we don't do 0-RTT. |
| 273 | |
| 274 | pskSuite := cipherSuiteTLS13ByID(sessionState.cipherSuite) |
| 275 | if pskSuite == nil || pskSuite.hash != hs.suite.hash { |
| 276 | continue |
| 277 | } |
| 278 | |
| 279 | // PSK connections don't re-establish client certificates, but carry |
| 280 | // them over in the session ticket. Ensure the presence of client certs |
| 281 | // in the ticket is consistent with the configured requirements. |
| 282 | sessionHasClientCerts := len(sessionState.certificate.Certificate) != 0 |
no test coverage detected