github.com/tumi8/quic-go@v0.37.4-tum/noninternal/handshake/crypto_setup.go (about) 1 package handshake 2 3 import ( 4 "bytes" 5 "context" 6 "crypto/tls" 7 "errors" 8 "fmt" 9 "net" 10 "sync" 11 "sync/atomic" 12 "time" 13 14 "github.com/tumi8/quic-go/noninternal/protocol" 15 "github.com/tumi8/quic-go/noninternal/qerr" 16 "github.com/tumi8/quic-go/noninternal/qtls" 17 "github.com/tumi8/quic-go/noninternal/utils" 18 "github.com/tumi8/quic-go/noninternal/wire" 19 "github.com/tumi8/quic-go/logging" 20 "github.com/tumi8/quic-go/quicvarint" 21 ) 22 23 type quicVersionContextKey struct{} 24 25 var QUICVersionContextKey = &quicVersionContextKey{} 26 27 const clientSessionStateRevision = 3 28 29 type cryptoSetup struct { 30 tlsConf *tls.Config 31 conn *qtls.QUICConn 32 33 events []Event 34 35 version protocol.VersionNumber 36 37 ourParams *wire.TransportParameters 38 peerParams *wire.TransportParameters 39 40 zeroRTTParameters *wire.TransportParameters 41 allow0RTT bool 42 43 rttStats *utils.RTTStats 44 45 tracer logging.ConnectionTracer 46 logger utils.Logger 47 48 perspective protocol.Perspective 49 50 mutex sync.Mutex // protects all members below 51 52 handshakeCompleteTime time.Time 53 54 zeroRTTOpener LongHeaderOpener // only set for the server 55 zeroRTTSealer LongHeaderSealer // only set for the client 56 57 initialOpener LongHeaderOpener 58 initialSealer LongHeaderSealer 59 60 handshakeOpener LongHeaderOpener 61 handshakeSealer LongHeaderSealer 62 63 used0RTT atomic.Bool 64 65 aead *updatableAEAD 66 has1RTTSealer bool 67 has1RTTOpener bool 68 } 69 70 var _ CryptoSetup = &cryptoSetup{} 71 72 // NewCryptoSetupClient creates a new crypto setup for the client 73 func NewCryptoSetupClient( 74 connID protocol.ConnectionID, 75 tp *wire.TransportParameters, 76 tlsConf *tls.Config, 77 enable0RTT bool, 78 rttStats *utils.RTTStats, 79 tracer logging.ConnectionTracer, 80 logger utils.Logger, 81 version protocol.VersionNumber, 82 ) CryptoSetup { 83 cs := newCryptoSetup( 84 connID, 85 tp, 86 rttStats, 87 tracer, 88 logger, 89 protocol.PerspectiveClient, 90 version, 91 ) 92 93 tlsConf = tlsConf.Clone() 94 tlsConf.MinVersion = tls.VersionTLS13 95 quicConf := &qtls.QUICConfig{TLSConfig: tlsConf} 96 qtls.SetupConfigForClient(quicConf, cs.marshalDataForSessionState, cs.handleDataFromSessionState) 97 cs.tlsConf = tlsConf 98 99 cs.conn = qtls.QUICClient(quicConf) 100 cs.conn.SetTransportParameters(cs.ourParams.Marshal(protocol.PerspectiveClient)) 101 102 return cs 103 } 104 105 // NewCryptoSetupServer creates a new crypto setup for the server 106 func NewCryptoSetupServer( 107 connID protocol.ConnectionID, 108 localAddr, remoteAddr net.Addr, 109 tp *wire.TransportParameters, 110 tlsConf *tls.Config, 111 allow0RTT bool, 112 rttStats *utils.RTTStats, 113 tracer logging.ConnectionTracer, 114 logger utils.Logger, 115 version protocol.VersionNumber, 116 ) CryptoSetup { 117 cs := newCryptoSetup( 118 connID, 119 tp, 120 rttStats, 121 tracer, 122 logger, 123 protocol.PerspectiveServer, 124 version, 125 ) 126 cs.allow0RTT = allow0RTT 127 128 quicConf := &qtls.QUICConfig{TLSConfig: tlsConf} 129 qtls.SetupConfigForServer(quicConf, cs.allow0RTT, cs.getDataForSessionTicket, cs.accept0RTT) 130 addConnToClientHelloInfo(quicConf.TLSConfig, localAddr, remoteAddr) 131 132 cs.tlsConf = quicConf.TLSConfig 133 cs.conn = qtls.QUICServer(quicConf) 134 135 return cs 136 } 137 138 // The tls.Config contains two callbacks that pass in a tls.ClientHelloInfo. 139 // Since crypto/tls doesn't do it, we need to make sure to set the Conn field with a fake net.Conn 140 // that allows the caller to get the local and the remote address. 141 func addConnToClientHelloInfo(conf *tls.Config, localAddr, remoteAddr net.Addr) { 142 if conf.GetConfigForClient != nil { 143 gcfc := conf.GetConfigForClient 144 conf.GetConfigForClient = func(info *tls.ClientHelloInfo) (*tls.Config, error) { 145 info.Conn = &conn{localAddr: localAddr, remoteAddr: remoteAddr} 146 c, err := gcfc(info) 147 if c != nil { 148 // We're returning a tls.Config here, so we need to apply this recursively. 149 addConnToClientHelloInfo(c, localAddr, remoteAddr) 150 } 151 return c, err 152 } 153 } 154 if conf.GetCertificate != nil { 155 gc := conf.GetCertificate 156 conf.GetCertificate = func(info *tls.ClientHelloInfo) (*tls.Certificate, error) { 157 info.Conn = &conn{localAddr: localAddr, remoteAddr: remoteAddr} 158 return gc(info) 159 } 160 } 161 } 162 163 func newCryptoSetup( 164 connID protocol.ConnectionID, 165 tp *wire.TransportParameters, 166 rttStats *utils.RTTStats, 167 tracer logging.ConnectionTracer, 168 logger utils.Logger, 169 perspective protocol.Perspective, 170 version protocol.VersionNumber, 171 ) *cryptoSetup { 172 initialSealer, initialOpener := NewInitialAEAD(connID, perspective, version) 173 if tracer != nil { 174 tracer.UpdatedKeyFromTLS(protocol.EncryptionInitial, protocol.PerspectiveClient) 175 tracer.UpdatedKeyFromTLS(protocol.EncryptionInitial, protocol.PerspectiveServer) 176 } 177 return &cryptoSetup{ 178 initialSealer: initialSealer, 179 initialOpener: initialOpener, 180 aead: newUpdatableAEAD(rttStats, tracer, logger, version), 181 events: make([]Event, 0, 16), 182 ourParams: tp, 183 rttStats: rttStats, 184 tracer: tracer, 185 logger: logger, 186 perspective: perspective, 187 version: version, 188 } 189 } 190 191 func (h *cryptoSetup) ChangeConnectionID(id protocol.ConnectionID) { 192 initialSealer, initialOpener := NewInitialAEAD(id, h.perspective, h.version) 193 h.initialSealer = initialSealer 194 h.initialOpener = initialOpener 195 if h.tracer != nil { 196 h.tracer.UpdatedKeyFromTLS(protocol.EncryptionInitial, protocol.PerspectiveClient) 197 h.tracer.UpdatedKeyFromTLS(protocol.EncryptionInitial, protocol.PerspectiveServer) 198 } 199 } 200 201 func (h *cryptoSetup) SetLargest1RTTAcked(pn protocol.PacketNumber) error { 202 return h.aead.SetLargestAcked(pn) 203 } 204 205 func (h *cryptoSetup) StartHandshake() error { 206 err := h.conn.Start(context.WithValue(context.Background(), QUICVersionContextKey, h.version)) 207 if err != nil { 208 return wrapError(err) 209 } 210 for { 211 ev := h.conn.NextEvent() 212 done, err := h.handleEvent(ev) 213 if err != nil { 214 return wrapError(err) 215 } 216 if done { 217 break 218 } 219 } 220 if h.perspective == protocol.PerspectiveClient { 221 if h.zeroRTTSealer != nil && h.zeroRTTParameters != nil { 222 h.logger.Debugf("Doing 0-RTT.") 223 h.events = append(h.events, Event{Kind: EventRestoredTransportParameters, TransportParameters: h.zeroRTTParameters}) 224 } else { 225 h.logger.Debugf("Not doing 0-RTT. Has sealer: %t, has params: %t", h.zeroRTTSealer != nil, h.zeroRTTParameters != nil) 226 } 227 } 228 return nil 229 } 230 231 // Close closes the crypto setup. 232 // It aborts the handshake, if it is still running. 233 func (h *cryptoSetup) Close() error { 234 return h.conn.Close() 235 } 236 237 // HandleMessage handles a TLS handshake message. 238 // It is called by the crypto streams when a new message is available. 239 func (h *cryptoSetup) HandleMessage(data []byte, encLevel protocol.EncryptionLevel) error { 240 if err := h.handleMessage(data, encLevel); err != nil { 241 return wrapError(err) 242 } 243 return nil 244 } 245 246 func (h *cryptoSetup) handleMessage(data []byte, encLevel protocol.EncryptionLevel) error { 247 if err := h.conn.HandleData(qtls.ToTLSEncryptionLevel(encLevel), data); err != nil { 248 return err 249 } 250 for { 251 ev := h.conn.NextEvent() 252 done, err := h.handleEvent(ev) 253 if err != nil { 254 return err 255 } 256 if done { 257 return nil 258 } 259 } 260 } 261 262 func (h *cryptoSetup) handleEvent(ev qtls.QUICEvent) (done bool, err error) { 263 switch ev.Kind { 264 case qtls.QUICNoEvent: 265 return true, nil 266 case qtls.QUICSetReadSecret: 267 h.SetReadKey(ev.Level, ev.Suite, ev.Data) 268 return false, nil 269 case qtls.QUICSetWriteSecret: 270 h.SetWriteKey(ev.Level, ev.Suite, ev.Data) 271 return false, nil 272 case qtls.QUICTransportParameters: 273 return false, h.handleTransportParameters(ev.Data) 274 case qtls.QUICTransportParametersRequired: 275 h.conn.SetTransportParameters(h.ourParams.Marshal(h.perspective)) 276 return false, nil 277 case qtls.QUICRejectedEarlyData: 278 h.rejected0RTT() 279 return false, nil 280 case qtls.QUICWriteData: 281 h.WriteRecord(ev.Level, ev.Data) 282 return false, nil 283 case qtls.QUICHandshakeDone: 284 h.handshakeComplete() 285 return false, nil 286 default: 287 return false, fmt.Errorf("unexpected event: %d", ev.Kind) 288 } 289 } 290 291 func (h *cryptoSetup) NextEvent() Event { 292 if len(h.events) == 0 { 293 return Event{Kind: EventNoEvent} 294 } 295 ev := h.events[0] 296 h.events = h.events[1:] 297 return ev 298 } 299 300 func (h *cryptoSetup) handleTransportParameters(data []byte) error { 301 var tp wire.TransportParameters 302 if err := tp.Unmarshal(data, h.perspective.Opposite()); err != nil { 303 return err 304 } 305 h.peerParams = &tp 306 h.events = append(h.events, Event{Kind: EventReceivedTransportParameters, TransportParameters: h.peerParams}) 307 return nil 308 } 309 310 // must be called after receiving the transport parameters 311 func (h *cryptoSetup) marshalDataForSessionState() []byte { 312 b := make([]byte, 0, 256) 313 b = quicvarint.Append(b, clientSessionStateRevision) 314 b = quicvarint.Append(b, uint64(h.rttStats.SmoothedRTT().Microseconds())) 315 return h.peerParams.MarshalForSessionTicket(b) 316 } 317 318 func (h *cryptoSetup) handleDataFromSessionState(data []byte) { 319 tp, err := h.handleDataFromSessionStateImpl(data) 320 if err != nil { 321 h.logger.Debugf("Restoring of transport parameters from session ticket failed: %s", err.Error()) 322 return 323 } 324 h.zeroRTTParameters = tp 325 } 326 327 func (h *cryptoSetup) handleDataFromSessionStateImpl(data []byte) (*wire.TransportParameters, error) { 328 r := bytes.NewReader(data) 329 ver, err := quicvarint.Read(r) 330 if err != nil { 331 return nil, err 332 } 333 if ver != clientSessionStateRevision { 334 return nil, fmt.Errorf("mismatching version. Got %d, expected %d", ver, clientSessionStateRevision) 335 } 336 rtt, err := quicvarint.Read(r) 337 if err != nil { 338 return nil, err 339 } 340 h.rttStats.SetInitialRTT(time.Duration(rtt) * time.Microsecond) 341 var tp wire.TransportParameters 342 if err := tp.UnmarshalFromSessionTicket(r); err != nil { 343 return nil, err 344 } 345 return &tp, nil 346 } 347 348 func (h *cryptoSetup) getDataForSessionTicket() []byte { 349 return (&sessionTicket{ 350 Parameters: h.ourParams, 351 RTT: h.rttStats.SmoothedRTT(), 352 }).Marshal() 353 } 354 355 // GetSessionTicket generates a new session ticket. 356 // Due to limitations in crypto/tls, it's only possible to generate a single session ticket per connection. 357 // It is only valid for the server. 358 func (h *cryptoSetup) GetSessionTicket() ([]byte, error) { 359 if h.tlsConf.SessionTicketsDisabled { 360 return nil, nil 361 } 362 if err := h.conn.SendSessionTicket(h.allow0RTT); err != nil { 363 return nil, err 364 } 365 ev := h.conn.NextEvent() 366 if ev.Kind != qtls.QUICWriteData || ev.Level != qtls.QUICEncryptionLevelApplication { 367 panic("crypto/tls bug: where's my session ticket?") 368 } 369 ticket := ev.Data 370 if ev := h.conn.NextEvent(); ev.Kind != qtls.QUICNoEvent { 371 panic("crypto/tls bug: why more than one ticket?") 372 } 373 return ticket, nil 374 } 375 376 // accept0RTT is called for the server when receiving the client's session ticket. 377 // It decides whether to accept 0-RTT. 378 func (h *cryptoSetup) accept0RTT(sessionTicketData []byte) bool { 379 var t sessionTicket 380 if err := t.Unmarshal(sessionTicketData); err != nil { 381 h.logger.Debugf("Unmarshalling transport parameters from session ticket failed: %s", err.Error()) 382 return false 383 } 384 valid := h.ourParams.ValidFor0RTT(t.Parameters) 385 if !valid { 386 h.logger.Debugf("Transport parameters changed. Rejecting 0-RTT.") 387 return false 388 } 389 if !h.allow0RTT { 390 h.logger.Debugf("0-RTT not allowed. Rejecting 0-RTT.") 391 return false 392 } 393 h.logger.Debugf("Accepting 0-RTT. Restoring RTT from session ticket: %s", t.RTT) 394 h.rttStats.SetInitialRTT(t.RTT) 395 return true 396 } 397 398 // rejected0RTT is called for the client when the server rejects 0-RTT. 399 func (h *cryptoSetup) rejected0RTT() { 400 h.logger.Debugf("0-RTT was rejected. Dropping 0-RTT keys.") 401 402 h.mutex.Lock() 403 had0RTTKeys := h.zeroRTTSealer != nil 404 h.zeroRTTSealer = nil 405 h.mutex.Unlock() 406 407 if had0RTTKeys { 408 h.events = append(h.events, Event{Kind: EventDiscard0RTTKeys}) 409 } 410 } 411 412 func (h *cryptoSetup) SetReadKey(el qtls.QUICEncryptionLevel, suiteID uint16, trafficSecret []byte) { 413 suite := getCipherSuite(suiteID) 414 h.mutex.Lock() 415 //nolint:exhaustive // The TLS stack doesn't export Initial keys. 416 switch el { 417 case qtls.QUICEncryptionLevelEarly: 418 if h.perspective == protocol.PerspectiveClient { 419 panic("Received 0-RTT read key for the client") 420 } 421 h.zeroRTTOpener = newLongHeaderOpener( 422 createAEAD(suite, trafficSecret, h.version), 423 newHeaderProtector(suite, trafficSecret, true, h.version), 424 ) 425 h.used0RTT.Store(true) 426 if h.logger.Debug() { 427 h.logger.Debugf("Installed 0-RTT Read keys (using %s)", tls.CipherSuiteName(suite.ID)) 428 } 429 case qtls.QUICEncryptionLevelHandshake: 430 h.handshakeOpener = newLongHeaderOpener( 431 createAEAD(suite, trafficSecret, h.version), 432 newHeaderProtector(suite, trafficSecret, true, h.version), 433 ) 434 if h.logger.Debug() { 435 h.logger.Debugf("Installed Handshake Read keys (using %s)", tls.CipherSuiteName(suite.ID)) 436 } 437 case qtls.QUICEncryptionLevelApplication: 438 h.aead.SetReadKey(suite, trafficSecret) 439 h.has1RTTOpener = true 440 if h.logger.Debug() { 441 h.logger.Debugf("Installed 1-RTT Read keys (using %s)", tls.CipherSuiteName(suite.ID)) 442 } 443 default: 444 panic("unexpected read encryption level") 445 } 446 h.mutex.Unlock() 447 h.events = append(h.events, Event{Kind: EventReceivedReadKeys}) 448 if h.tracer != nil { 449 h.tracer.UpdatedKeyFromTLS(qtls.FromTLSEncryptionLevel(el), h.perspective.Opposite()) 450 } 451 } 452 453 func (h *cryptoSetup) SetWriteKey(el qtls.QUICEncryptionLevel, suiteID uint16, trafficSecret []byte) { 454 suite := getCipherSuite(suiteID) 455 h.mutex.Lock() 456 //nolint:exhaustive // The TLS stack doesn't export Initial keys. 457 switch el { 458 case qtls.QUICEncryptionLevelEarly: 459 if h.perspective == protocol.PerspectiveServer { 460 panic("Received 0-RTT write key for the server") 461 } 462 h.zeroRTTSealer = newLongHeaderSealer( 463 createAEAD(suite, trafficSecret, h.version), 464 newHeaderProtector(suite, trafficSecret, true, h.version), 465 ) 466 h.mutex.Unlock() 467 if h.logger.Debug() { 468 h.logger.Debugf("Installed 0-RTT Write keys (using %s)", tls.CipherSuiteName(suite.ID)) 469 } 470 if h.tracer != nil { 471 h.tracer.UpdatedKeyFromTLS(protocol.Encryption0RTT, h.perspective) 472 } 473 // don't set used0RTT here. 0-RTT might still get rejected. 474 return 475 case qtls.QUICEncryptionLevelHandshake: 476 h.handshakeSealer = newLongHeaderSealer( 477 createAEAD(suite, trafficSecret, h.version), 478 newHeaderProtector(suite, trafficSecret, true, h.version), 479 ) 480 if h.logger.Debug() { 481 h.logger.Debugf("Installed Handshake Write keys (using %s)", tls.CipherSuiteName(suite.ID)) 482 } 483 case qtls.QUICEncryptionLevelApplication: 484 h.aead.SetWriteKey(suite, trafficSecret) 485 h.has1RTTSealer = true 486 if h.logger.Debug() { 487 h.logger.Debugf("Installed 1-RTT Write keys (using %s)", tls.CipherSuiteName(suite.ID)) 488 } 489 if h.zeroRTTSealer != nil { 490 // Once we receive handshake keys, we know that 0-RTT was not rejected. 491 h.used0RTT.Store(true) 492 h.zeroRTTSealer = nil 493 h.logger.Debugf("Dropping 0-RTT keys.") 494 if h.tracer != nil { 495 h.tracer.DroppedEncryptionLevel(protocol.Encryption0RTT) 496 } 497 } 498 default: 499 panic("unexpected write encryption level") 500 } 501 h.mutex.Unlock() 502 if h.tracer != nil { 503 h.tracer.UpdatedKeyFromTLS(qtls.FromTLSEncryptionLevel(el), h.perspective) 504 } 505 } 506 507 // WriteRecord is called when TLS writes data 508 func (h *cryptoSetup) WriteRecord(encLevel qtls.QUICEncryptionLevel, p []byte) { 509 //nolint:exhaustive // handshake records can only be written for Initial and Handshake. 510 switch encLevel { 511 case qtls.QUICEncryptionLevelInitial: 512 h.events = append(h.events, Event{Kind: EventWriteInitialData, Data: p}) 513 case qtls.QUICEncryptionLevelHandshake: 514 h.events = append(h.events, Event{Kind: EventWriteHandshakeData, Data: p}) 515 case qtls.QUICEncryptionLevelApplication: 516 panic("unexpected write") 517 default: 518 panic(fmt.Sprintf("unexpected write encryption level: %s", encLevel)) 519 } 520 } 521 522 func (h *cryptoSetup) DiscardInitialKeys() { 523 h.mutex.Lock() 524 dropped := h.initialOpener != nil 525 h.initialOpener = nil 526 h.initialSealer = nil 527 h.mutex.Unlock() 528 if dropped { 529 h.logger.Debugf("Dropping Initial keys.") 530 } 531 } 532 533 func (h *cryptoSetup) handshakeComplete() { 534 h.handshakeCompleteTime = time.Now() 535 h.events = append(h.events, Event{Kind: EventHandshakeComplete}) 536 } 537 538 func (h *cryptoSetup) SetHandshakeConfirmed() { 539 h.aead.SetHandshakeConfirmed() 540 // drop Handshake keys 541 var dropped bool 542 h.mutex.Lock() 543 if h.handshakeOpener != nil { 544 h.handshakeOpener = nil 545 h.handshakeSealer = nil 546 dropped = true 547 } 548 h.mutex.Unlock() 549 if dropped { 550 h.logger.Debugf("Dropping Handshake keys.") 551 } 552 } 553 554 func (h *cryptoSetup) GetInitialSealer() (LongHeaderSealer, error) { 555 h.mutex.Lock() 556 defer h.mutex.Unlock() 557 558 if h.initialSealer == nil { 559 return nil, ErrKeysDropped 560 } 561 return h.initialSealer, nil 562 } 563 564 func (h *cryptoSetup) Get0RTTSealer() (LongHeaderSealer, error) { 565 h.mutex.Lock() 566 defer h.mutex.Unlock() 567 568 if h.zeroRTTSealer == nil { 569 return nil, ErrKeysDropped 570 } 571 return h.zeroRTTSealer, nil 572 } 573 574 func (h *cryptoSetup) GetHandshakeSealer() (LongHeaderSealer, error) { 575 h.mutex.Lock() 576 defer h.mutex.Unlock() 577 578 if h.handshakeSealer == nil { 579 if h.initialSealer == nil { 580 return nil, ErrKeysDropped 581 } 582 return nil, ErrKeysNotYetAvailable 583 } 584 return h.handshakeSealer, nil 585 } 586 587 func (h *cryptoSetup) Get1RTTSealer() (ShortHeaderSealer, error) { 588 h.mutex.Lock() 589 defer h.mutex.Unlock() 590 591 if !h.has1RTTSealer { 592 return nil, ErrKeysNotYetAvailable 593 } 594 return h.aead, nil 595 } 596 597 func (h *cryptoSetup) GetInitialOpener() (LongHeaderOpener, error) { 598 h.mutex.Lock() 599 defer h.mutex.Unlock() 600 601 if h.initialOpener == nil { 602 return nil, ErrKeysDropped 603 } 604 return h.initialOpener, nil 605 } 606 607 func (h *cryptoSetup) Get0RTTOpener() (LongHeaderOpener, error) { 608 h.mutex.Lock() 609 defer h.mutex.Unlock() 610 611 if h.zeroRTTOpener == nil { 612 if h.initialOpener != nil { 613 return nil, ErrKeysNotYetAvailable 614 } 615 // if the initial opener is also not available, the keys were already dropped 616 return nil, ErrKeysDropped 617 } 618 return h.zeroRTTOpener, nil 619 } 620 621 func (h *cryptoSetup) GetHandshakeOpener() (LongHeaderOpener, error) { 622 h.mutex.Lock() 623 defer h.mutex.Unlock() 624 625 if h.handshakeOpener == nil { 626 if h.initialOpener != nil { 627 return nil, ErrKeysNotYetAvailable 628 } 629 // if the initial opener is also not available, the keys were already dropped 630 return nil, ErrKeysDropped 631 } 632 return h.handshakeOpener, nil 633 } 634 635 func (h *cryptoSetup) Get1RTTOpener() (ShortHeaderOpener, error) { 636 h.mutex.Lock() 637 defer h.mutex.Unlock() 638 639 if h.zeroRTTOpener != nil && time.Since(h.handshakeCompleteTime) > 3*h.rttStats.PTO(true) { 640 h.zeroRTTOpener = nil 641 h.logger.Debugf("Dropping 0-RTT keys.") 642 if h.tracer != nil { 643 h.tracer.DroppedEncryptionLevel(protocol.Encryption0RTT) 644 } 645 } 646 647 if !h.has1RTTOpener { 648 return nil, ErrKeysNotYetAvailable 649 } 650 return h.aead, nil 651 } 652 653 func (h *cryptoSetup) ConnectionState() ConnectionState { 654 655 tmp := h.conn.ConnectionState() 656 tmp_state := tls.ConnectionState{ 657 Version: tmp.Version, 658 HandshakeComplete: tmp.HandshakeComplete, 659 DidResume: tmp.DidResume, 660 CipherSuite: tmp.CipherSuite, 661 NegotiatedProtocol: tmp.NegotiatedProtocol, 662 NegotiatedProtocolIsMutual: tmp.NegotiatedProtocolIsMutual, 663 ServerName: tmp.ServerName, 664 PeerCertificates: tmp.PeerCertificates, 665 VerifiedChains: tmp.VerifiedChains, 666 SignedCertificateTimestamps: tmp.SignedCertificateTimestamps, 667 OCSPResponse: tmp.OCSPResponse, 668 TLSUnique: tmp.TLSUnique, 669 } 670 671 672 return ConnectionState{ 673 ConnectionState: tmp_state, 674 Used0RTT: h.used0RTT.Load(), 675 ConnectionInfo: *h.conn, 676 } 677 } 678 679 func wrapError(err error) error { 680 if alertErr := qtls.AlertError(0); errors.As(err, &alertErr) && alertErr != 80 { 681 return qerr.NewLocalCryptoError(uint8(alertErr), err.Error()) 682 } 683 return &qerr.TransportError{ErrorCode: qerr.InternalError, ErrorMessage: err.Error()} 684 }