()
| 326 | } |
| 327 | |
| 328 | func (hs *serverHandshakeState) pickCipherSuite() error { |
| 329 | c := hs.c |
| 330 | |
| 331 | preferenceOrder := cipherSuitesPreferenceOrder |
| 332 | if !hasAESGCMHardwareSupport || !aesgcmPreferred(hs.clientHello.cipherSuites) { |
| 333 | preferenceOrder = cipherSuitesPreferenceOrderNoAES |
| 334 | } |
| 335 | |
| 336 | configCipherSuites := c.config.cipherSuites() |
| 337 | preferenceList := make([]uint16, 0, len(configCipherSuites)) |
| 338 | for _, suiteID := range preferenceOrder { |
| 339 | for _, id := range configCipherSuites { |
| 340 | if id == suiteID { |
| 341 | preferenceList = append(preferenceList, id) |
| 342 | break |
| 343 | } |
| 344 | } |
| 345 | } |
| 346 | |
| 347 | hs.suite = selectCipherSuite(preferenceList, hs.clientHello.cipherSuites, hs.cipherSuiteOk) |
| 348 | if hs.suite == nil { |
| 349 | c.sendAlert(alertHandshakeFailure) |
| 350 | return errors.New("tls: no cipher suite supported by both client and server") |
| 351 | } |
| 352 | c.cipherSuite = hs.suite.id |
| 353 | |
| 354 | for _, id := range hs.clientHello.cipherSuites { |
| 355 | if id == TLS_FALLBACK_SCSV { |
| 356 | // The client is doing a fallback connection. See RFC 7507. |
| 357 | if hs.clientHello.vers < c.config.maxSupportedVersion(roleClient) { |
| 358 | c.sendAlert(alertInappropriateFallback) |
| 359 | return errors.New("tls: client using inappropriate protocol fallback") |
| 360 | } |
| 361 | break |
| 362 | } |
| 363 | } |
| 364 | |
| 365 | return nil |
| 366 | } |
| 367 | |
| 368 | func (hs *serverHandshakeState) cipherSuiteOk(c *cipherSuite) bool { |
| 369 | if c.flags&suiteECDHE != 0 { |
no test coverage detected