github.com/zmap/zcrypto@v0.0.0-20240512203510-0fef58d9a9db/tls/handshake_extensions.go (about)

     1  package tls
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  )
     7  
     8  type NullExtension struct {
     9  }
    10  
    11  func (e *NullExtension) WriteToConfig(c *Config) error {
    12  	return nil
    13  }
    14  
    15  func (e *NullExtension) CheckImplemented() error {
    16  	return nil
    17  }
    18  
    19  func (e *NullExtension) Marshal() []byte {
    20  	return []byte{}
    21  }
    22  
    23  type SNIExtension struct {
    24  	Domains      []string
    25  	Autopopulate bool
    26  }
    27  
    28  func (e *SNIExtension) WriteToConfig(c *Config) error {
    29  	if e.Autopopulate {
    30  		for i, ext := range c.ClientFingerprintConfiguration.Extensions {
    31  			switch ext.(type) {
    32  			case *SNIExtension:
    33  				if c.ServerName == "" {
    34  					c.ClientFingerprintConfiguration.Extensions[i] = &NullExtension{}
    35  				} else {
    36  					c.ClientFingerprintConfiguration.Extensions[i] = &SNIExtension{
    37  						Domains:      []string{c.ServerName},
    38  						Autopopulate: true,
    39  					}
    40  				}
    41  			default:
    42  				continue
    43  			}
    44  		}
    45  	}
    46  	// If a server name is not specified in the config, but is available in the extensions
    47  	// we set it for certificate validation later on
    48  	if c.ServerName == "" && len(e.Domains) > 0 {
    49  		c.ServerName = e.Domains[0]
    50  	}
    51  	return nil
    52  }
    53  
    54  func (e *SNIExtension) CheckImplemented() error {
    55  	return nil
    56  }
    57  
    58  func (e *SNIExtension) Marshal() []byte {
    59  	result := []byte{}
    60  	for _, domain := range e.Domains {
    61  		current := make([]byte, 2+len(domain))
    62  		copy(current[2:], []byte(domain))
    63  		current[0] = uint8(len(domain) >> 8)
    64  		current[1] = uint8(len(domain))
    65  		result = append(result, current...)
    66  	}
    67  	sniHeader := make([]byte, 3)
    68  	sniHeader[0] = uint8((len(result) + 1) >> 8)
    69  	sniHeader[1] = uint8((len(result) + 1))
    70  	sniHeader[2] = 0
    71  	result = append(sniHeader, result...)
    72  
    73  	extHeader := make([]byte, 4)
    74  	extHeader[0] = 0
    75  	extHeader[1] = 0
    76  	extHeader[2] = uint8((len(result)) >> 8)
    77  	extHeader[3] = uint8((len(result)))
    78  	result = append(extHeader, result...)
    79  
    80  	return result
    81  }
    82  
    83  type ALPNExtension struct {
    84  	Protocols []string
    85  }
    86  
    87  func (e *ALPNExtension) WriteToConfig(c *Config) error {
    88  	c.NextProtos = e.Protocols
    89  	return nil
    90  }
    91  
    92  func (e *ALPNExtension) CheckImplemented() error {
    93  	return nil
    94  }
    95  
    96  func (e *ALPNExtension) Marshal() []byte {
    97  	result := []byte{}
    98  	for _, protocol := range e.Protocols {
    99  		current := make([]byte, 1+len(protocol))
   100  		copy(current[1:], []byte(protocol))
   101  		current[0] = uint8(len(protocol))
   102  		result = append(result, current...)
   103  	}
   104  	alpnHeader := make([]byte, 2)
   105  	alpnHeader[0] = uint8((len(result)) >> 8)
   106  	alpnHeader[1] = uint8((len(result)))
   107  	result = append(alpnHeader, result...)
   108  
   109  	extHeader := make([]byte, 4)
   110  	extHeader[0] = byte(extensionALPN >> 8)
   111  	extHeader[1] = byte(extensionALPN & 0xff)
   112  	extHeader[2] = uint8((len(result)) >> 8)
   113  	extHeader[3] = uint8((len(result)))
   114  	result = append(extHeader, result...)
   115  
   116  	return result
   117  }
   118  
   119  type SecureRenegotiationExtension struct {
   120  }
   121  
   122  func (e *SecureRenegotiationExtension) WriteToConfig(c *Config) error {
   123  	return nil
   124  }
   125  
   126  func (e *SecureRenegotiationExtension) CheckImplemented() error {
   127  	return nil
   128  }
   129  
   130  func (e *SecureRenegotiationExtension) Marshal() []byte {
   131  	result := make([]byte, 5)
   132  	result[0] = byte(extensionRenegotiationInfo >> 8)
   133  	result[1] = byte(extensionRenegotiationInfo & 0xff)
   134  	result[2] = 0
   135  	result[3] = 1
   136  	result[4] = 0
   137  	return result
   138  }
   139  
   140  type ExtendedMasterSecretExtension struct {
   141  }
   142  
   143  func (e *ExtendedMasterSecretExtension) WriteToConfig(c *Config) error {
   144  	c.ExtendedMasterSecret = true
   145  	return nil
   146  }
   147  
   148  func (e *ExtendedMasterSecretExtension) CheckImplemented() error {
   149  	return nil
   150  }
   151  
   152  func (e *ExtendedMasterSecretExtension) Marshal() []byte {
   153  	result := make([]byte, 4)
   154  	result[0] = byte(extensionExtendedMasterSecret >> 8)
   155  	result[1] = byte(extensionExtendedMasterSecret & 0xff)
   156  	result[2] = 0
   157  	result[3] = 0
   158  	return result
   159  }
   160  
   161  type NextProtocolNegotiationExtension struct {
   162  	Protocols []string
   163  }
   164  
   165  func (e *NextProtocolNegotiationExtension) WriteToConfig(c *Config) error {
   166  	c.NextProtos = e.Protocols
   167  	return nil
   168  }
   169  
   170  func (e *NextProtocolNegotiationExtension) CheckImplemented() error {
   171  	return nil
   172  }
   173  
   174  func (e *NextProtocolNegotiationExtension) Marshal() []byte {
   175  	result := make([]byte, 4)
   176  	result[0] = byte(extensionNextProtoNeg >> 8)
   177  	result[1] = byte(extensionNextProtoNeg & 0xff)
   178  	result[2] = 0
   179  	result[3] = 0
   180  	return result
   181  }
   182  
   183  type StatusRequestExtension struct {
   184  }
   185  
   186  func (e *StatusRequestExtension) WriteToConfig(c *Config) error {
   187  	return nil
   188  }
   189  
   190  func (e *StatusRequestExtension) CheckImplemented() error {
   191  	return nil
   192  }
   193  
   194  func (e *StatusRequestExtension) Marshal() []byte {
   195  	result := make([]byte, 9)
   196  	result[0] = byte(extensionStatusRequest >> 8)
   197  	result[1] = byte(extensionStatusRequest & 0xff)
   198  	result[2] = 0
   199  	result[3] = 5
   200  	result[4] = 1 // OCSP type
   201  	result[5] = 0
   202  	result[6] = 0
   203  	result[7] = 0
   204  	result[8] = 0
   205  	return result
   206  }
   207  
   208  type SCTExtension struct {
   209  }
   210  
   211  func (e *SCTExtension) WriteToConfig(c *Config) error {
   212  	c.SignedCertificateTimestampExt = true
   213  	return nil
   214  }
   215  
   216  func (e *SCTExtension) CheckImplemented() error {
   217  	return nil
   218  }
   219  
   220  func (e *SCTExtension) Marshal() []byte {
   221  	result := make([]byte, 4)
   222  	result[0] = byte(extensionSCT >> 8)
   223  	result[1] = byte(extensionSCT & 0xff)
   224  	result[2] = 0
   225  	result[3] = 0
   226  	return result
   227  }
   228  
   229  type SupportedCurvesExtension struct {
   230  	Curves []CurveID
   231  }
   232  
   233  func (e *SupportedCurvesExtension) WriteToConfig(c *Config) error {
   234  	c.CurvePreferences = e.Curves
   235  	return nil
   236  }
   237  
   238  func (e *SupportedCurvesExtension) CheckImplemented() error {
   239  	for _, curve := range e.Curves {
   240  		found := false
   241  		for _, supported := range defaultCurvePreferences {
   242  			if curve == supported {
   243  				found = true
   244  			}
   245  		}
   246  		if !found {
   247  			return fmt.Errorf("Unsupported CurveID %d", curve)
   248  		}
   249  	}
   250  	return nil
   251  }
   252  
   253  func (e *SupportedCurvesExtension) Marshal() []byte {
   254  	result := make([]byte, 6+2*len(e.Curves))
   255  	result[0] = byte(extensionSupportedCurves >> 8)
   256  	result[1] = byte(extensionSupportedCurves & 0xff)
   257  	result[2] = uint8((2 + 2*len(e.Curves)) >> 8)
   258  	result[3] = uint8((2 + 2*len(e.Curves)))
   259  	result[4] = uint8((2 * len(e.Curves)) >> 8)
   260  	result[5] = uint8((2 * len(e.Curves)))
   261  	for i, curve := range e.Curves {
   262  		result[6+2*i] = uint8(curve >> 8)
   263  		result[7+2*i] = uint8(curve)
   264  	}
   265  	return result
   266  }
   267  
   268  type PointFormatExtension struct {
   269  	Formats []uint8
   270  }
   271  
   272  func (e *PointFormatExtension) WriteToConfig(c *Config) error {
   273  	return nil
   274  }
   275  
   276  func (e *PointFormatExtension) CheckImplemented() error {
   277  	for _, format := range e.Formats {
   278  		if format != pointFormatUncompressed {
   279  			return fmt.Errorf("Unsupported EC Point Format %d", format)
   280  		}
   281  	}
   282  	return nil
   283  }
   284  
   285  func (e *PointFormatExtension) Marshal() []byte {
   286  	result := make([]byte, 5+len(e.Formats))
   287  	result[0] = byte(extensionSupportedPoints >> 8)
   288  	result[1] = byte(extensionSupportedPoints & 0xff)
   289  	result[2] = uint8((1 + len(e.Formats)) >> 8)
   290  	result[3] = uint8((1 + len(e.Formats)))
   291  	result[4] = uint8((len(e.Formats)))
   292  	for i, format := range e.Formats {
   293  		result[5+i] = format
   294  	}
   295  	return result
   296  }
   297  
   298  type SessionTicketExtension struct {
   299  	Ticket       []byte
   300  	Autopopulate bool
   301  }
   302  
   303  func (e *SessionTicketExtension) WriteToConfig(c *Config) error {
   304  	c.ForceSessionTicketExt = true
   305  	return nil
   306  }
   307  
   308  func (e *SessionTicketExtension) CheckImplemented() error {
   309  	return nil
   310  }
   311  
   312  func (e *SessionTicketExtension) Marshal() []byte {
   313  	result := make([]byte, 4+len(e.Ticket))
   314  	result[0] = byte(extensionSessionTicket >> 8)
   315  	result[1] = byte(extensionSessionTicket & 0xff)
   316  	result[2] = uint8(len(e.Ticket) >> 8)
   317  	result[3] = uint8(len(e.Ticket))
   318  	if len(e.Ticket) > 0 {
   319  		copy(result[4:], e.Ticket)
   320  	}
   321  	return result
   322  }
   323  
   324  type HeartbeatExtension struct {
   325  	Mode byte
   326  }
   327  
   328  func (e *HeartbeatExtension) WriteToConfig(c *Config) error {
   329  	return nil
   330  }
   331  
   332  func (e *HeartbeatExtension) CheckImplemented() error {
   333  	return nil
   334  }
   335  
   336  func (e *HeartbeatExtension) Marshal() []byte {
   337  	result := make([]byte, 5)
   338  	result[0] = byte(extensionHeartbeat >> 8)
   339  	result[1] = byte(extensionHeartbeat & 0xff)
   340  	result[2] = uint8(1 >> 8)
   341  	result[3] = uint8(1)
   342  	result[4] = e.Mode
   343  	return result
   344  }
   345  
   346  type SignatureAlgorithmExtension struct {
   347  	SignatureAndHashes []uint16
   348  }
   349  
   350  func (e *SignatureAlgorithmExtension) WriteToConfig(c *Config) error {
   351  	c.SignatureAndHashes = e.getStructuredAlgorithms()
   352  	return nil
   353  }
   354  
   355  func (e *SignatureAlgorithmExtension) CheckImplemented() error {
   356  	for _, algs := range e.getStructuredAlgorithms() {
   357  		found := false
   358  		for _, supported := range supportedSKXSignatureAlgorithms {
   359  			if algs.Hash == supported.Hash && algs.Signature == supported.Signature {
   360  				found = true
   361  				break
   362  			}
   363  		}
   364  		if !found {
   365  			return errors.New(fmt.Sprintf("Unsupported Hash and Signature Algorithm (%d, %d)", algs.Hash, algs.Signature))
   366  		}
   367  	}
   368  	return nil
   369  }
   370  
   371  func (e *SignatureAlgorithmExtension) getStructuredAlgorithms() []SigAndHash {
   372  	result := make([]SigAndHash, len(e.SignatureAndHashes))
   373  	for i, alg := range e.SignatureAndHashes {
   374  		result[i].Hash = uint8(alg >> 8)
   375  		result[i].Signature = uint8(alg)
   376  	}
   377  	return result
   378  }
   379  
   380  func (e *SignatureAlgorithmExtension) Marshal() []byte {
   381  	result := make([]byte, 6+2*len(e.SignatureAndHashes))
   382  	result[0] = byte(extensionSignatureAlgorithms >> 8)
   383  	result[1] = byte(extensionSignatureAlgorithms & 0xff)
   384  	result[2] = uint8((2 + 2*len(e.SignatureAndHashes)) >> 8)
   385  	result[3] = uint8((2 + 2*len(e.SignatureAndHashes)))
   386  	result[4] = uint8((2 * len(e.SignatureAndHashes)) >> 8)
   387  	result[5] = uint8((2 * len(e.SignatureAndHashes)))
   388  	for i, pair := range e.getStructuredAlgorithms() {
   389  		result[6+2*i] = uint8(pair.Hash)
   390  		result[7+2*i] = uint8(pair.Signature)
   391  	}
   392  	return result
   393  }