...

Source file src/golang.org/x/net/internal/quic/tls.go

Documentation: golang.org/x/net/internal/quic

     1  // Copyright 2023 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build go1.21
     6  
     7  package quic
     8  
     9  import (
    10  	"context"
    11  	"crypto/tls"
    12  	"errors"
    13  	"fmt"
    14  	"time"
    15  )
    16  
    17  // startTLS starts the TLS handshake.
    18  func (c *Conn) startTLS(now time.Time, initialConnID []byte, params transportParameters) error {
    19  	c.keysInitial = initialKeys(initialConnID, c.side)
    20  
    21  	qconfig := &tls.QUICConfig{TLSConfig: c.config.TLSConfig}
    22  	if c.side == clientSide {
    23  		c.tls = tls.QUICClient(qconfig)
    24  	} else {
    25  		c.tls = tls.QUICServer(qconfig)
    26  	}
    27  	c.tls.SetTransportParameters(marshalTransportParameters(params))
    28  	// TODO: We don't need or want a context for cancelation here,
    29  	// but users can use a context to plumb values through to hooks defined
    30  	// in the tls.Config. Pass through a context.
    31  	if err := c.tls.Start(context.TODO()); err != nil {
    32  		return err
    33  	}
    34  	return c.handleTLSEvents(now)
    35  }
    36  
    37  func (c *Conn) handleTLSEvents(now time.Time) error {
    38  	for {
    39  		e := c.tls.NextEvent()
    40  		if c.testHooks != nil {
    41  			c.testHooks.handleTLSEvent(e)
    42  		}
    43  		switch e.Kind {
    44  		case tls.QUICNoEvent:
    45  			return nil
    46  		case tls.QUICSetReadSecret:
    47  			if err := checkCipherSuite(e.Suite); err != nil {
    48  				return err
    49  			}
    50  			switch e.Level {
    51  			case tls.QUICEncryptionLevelHandshake:
    52  				c.keysHandshake.r.init(e.Suite, e.Data)
    53  			case tls.QUICEncryptionLevelApplication:
    54  				c.keysAppData.r.init(e.Suite, e.Data)
    55  			}
    56  		case tls.QUICSetWriteSecret:
    57  			if err := checkCipherSuite(e.Suite); err != nil {
    58  				return err
    59  			}
    60  			switch e.Level {
    61  			case tls.QUICEncryptionLevelHandshake:
    62  				c.keysHandshake.w.init(e.Suite, e.Data)
    63  			case tls.QUICEncryptionLevelApplication:
    64  				c.keysAppData.w.init(e.Suite, e.Data)
    65  			}
    66  		case tls.QUICWriteData:
    67  			var space numberSpace
    68  			switch e.Level {
    69  			case tls.QUICEncryptionLevelInitial:
    70  				space = initialSpace
    71  			case tls.QUICEncryptionLevelHandshake:
    72  				space = handshakeSpace
    73  			case tls.QUICEncryptionLevelApplication:
    74  				space = appDataSpace
    75  			default:
    76  				return fmt.Errorf("quic: internal error: write handshake data at level %v", e.Level)
    77  			}
    78  			c.crypto[space].write(e.Data)
    79  		case tls.QUICHandshakeDone:
    80  			if c.side == serverSide {
    81  				// "[...] the TLS handshake is considered confirmed
    82  				// at the server when the handshake completes."
    83  				// https://www.rfc-editor.org/rfc/rfc9001#section-4.1.2-1
    84  				c.confirmHandshake(now)
    85  			}
    86  			c.handshakeDone()
    87  		case tls.QUICTransportParameters:
    88  			params, err := unmarshalTransportParams(e.Data)
    89  			if err != nil {
    90  				return err
    91  			}
    92  			if err := c.receiveTransportParameters(params); err != nil {
    93  				return err
    94  			}
    95  		}
    96  	}
    97  }
    98  
    99  // handleCrypto processes data received in a CRYPTO frame.
   100  func (c *Conn) handleCrypto(now time.Time, space numberSpace, off int64, data []byte) error {
   101  	var level tls.QUICEncryptionLevel
   102  	switch space {
   103  	case initialSpace:
   104  		level = tls.QUICEncryptionLevelInitial
   105  	case handshakeSpace:
   106  		level = tls.QUICEncryptionLevelHandshake
   107  	case appDataSpace:
   108  		level = tls.QUICEncryptionLevelApplication
   109  	default:
   110  		return errors.New("quic: internal error: received CRYPTO frame in unexpected number space")
   111  	}
   112  	err := c.crypto[space].handleCrypto(off, data, func(b []byte) error {
   113  		return c.tls.HandleData(level, b)
   114  	})
   115  	if err != nil {
   116  		return err
   117  	}
   118  	return c.handleTLSEvents(now)
   119  }
   120  

View as plain text