git.prognetwork.ru/x0r/utls@v1.3.3/u_handshake_messages.go (about)

     1  // Copyright 2022 uTLS 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  package tls
     6  
     7  import (
     8  	"golang.org/x/crypto/cryptobyte"
     9  )
    10  
    11  // Only implemented client-side, for server certificates.
    12  // Alternate certificate message formats (https://datatracker.ietf.org/doc/html/rfc7250) are not
    13  // supported.
    14  // https://datatracker.ietf.org/doc/html/rfc8879
    15  type utlsCompressedCertificateMsg struct {
    16  	raw []byte
    17  
    18  	algorithm                    uint16
    19  	uncompressedLength           uint32 // uint24
    20  	compressedCertificateMessage []byte
    21  }
    22  
    23  func (m *utlsCompressedCertificateMsg) marshal() ([]byte, error) {
    24  	if m.raw != nil {
    25  		return m.raw, nil
    26  	}
    27  
    28  	var b cryptobyte.Builder
    29  	b.AddUint8(utlsTypeCompressedCertificate)
    30  	b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
    31  		b.AddUint16(m.algorithm)
    32  		b.AddUint24(m.uncompressedLength)
    33  		b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
    34  			b.AddBytes(m.compressedCertificateMessage)
    35  		})
    36  	})
    37  
    38  	var err error
    39  	m.raw, err = b.Bytes()
    40  	return m.raw, err
    41  }
    42  
    43  func (m *utlsCompressedCertificateMsg) unmarshal(data []byte) bool {
    44  	*m = utlsCompressedCertificateMsg{raw: data}
    45  	s := cryptobyte.String(data)
    46  
    47  	if !s.Skip(4) || // message type and uint24 length field
    48  		!s.ReadUint16(&m.algorithm) ||
    49  		!s.ReadUint24(&m.uncompressedLength) ||
    50  		!readUint24LengthPrefixed(&s, &m.compressedCertificateMessage) {
    51  		return false
    52  	}
    53  	return true
    54  }
    55  
    56  type utlsEncryptedExtensionsMsgExtraFields struct {
    57  	hasApplicationSettings bool
    58  	applicationSettings    []byte
    59  	customExtension        []byte
    60  }
    61  
    62  func (m *encryptedExtensionsMsg) utlsUnmarshal(extension uint16, extData cryptobyte.String) bool {
    63  	switch extension {
    64  	case utlsExtensionApplicationSettings:
    65  		m.utls.hasApplicationSettings = true
    66  		m.utls.applicationSettings = []byte(extData)
    67  	}
    68  	return true // success/unknown extension
    69  }
    70  
    71  type utlsClientEncryptedExtensionsMsg struct {
    72  	raw                    []byte
    73  	applicationSettings    []byte
    74  	hasApplicationSettings bool
    75  	customExtension        []byte
    76  }
    77  
    78  func (m *utlsClientEncryptedExtensionsMsg) marshal() (x []byte, err error) {
    79  	if m.raw != nil {
    80  		return m.raw, nil
    81  	}
    82  
    83  	var builder cryptobyte.Builder
    84  	builder.AddUint8(typeEncryptedExtensions)
    85  	builder.AddUint24LengthPrefixed(func(body *cryptobyte.Builder) {
    86  		body.AddUint16LengthPrefixed(func(extensions *cryptobyte.Builder) {
    87  			if m.hasApplicationSettings {
    88  				extensions.AddUint16(utlsExtensionApplicationSettings)
    89  				extensions.AddUint16LengthPrefixed(func(msg *cryptobyte.Builder) {
    90  					msg.AddBytes(m.applicationSettings)
    91  				})
    92  			}
    93  			if len(m.customExtension) > 0 {
    94  				extensions.AddUint16(utlsFakeExtensionCustom)
    95  				extensions.AddUint16LengthPrefixed(func(msg *cryptobyte.Builder) {
    96  					msg.AddBytes(m.customExtension)
    97  				})
    98  			}
    99  		})
   100  	})
   101  
   102  	m.raw, err = builder.Bytes()
   103  	return m.raw, err
   104  }
   105  
   106  func (m *utlsClientEncryptedExtensionsMsg) unmarshal(data []byte) bool {
   107  	*m = utlsClientEncryptedExtensionsMsg{raw: data}
   108  	s := cryptobyte.String(data)
   109  
   110  	var extensions cryptobyte.String
   111  	if !s.Skip(4) || // message type and uint24 length field
   112  		!s.ReadUint16LengthPrefixed(&extensions) || !s.Empty() {
   113  		return false
   114  	}
   115  
   116  	for !extensions.Empty() {
   117  		var extension uint16
   118  		var extData cryptobyte.String
   119  		if !extensions.ReadUint16(&extension) ||
   120  			!extensions.ReadUint16LengthPrefixed(&extData) {
   121  			return false
   122  		}
   123  
   124  		switch extension {
   125  		case utlsExtensionApplicationSettings:
   126  			m.hasApplicationSettings = true
   127  			m.applicationSettings = []byte(extData)
   128  		default:
   129  			// Unknown extensions are illegal in EncryptedExtensions.
   130  			return false
   131  		}
   132  	}
   133  	return true
   134  }