gitlab.com/go-extension/tls@v0.0.0-20240304171319-e6745021905e/extension_grease.go (about)

     1  // Copyright 2009 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  package tls
     6  
     7  import (
     8  	"encoding/binary"
     9  	"io"
    10  
    11  	"golang.org/x/crypto/cryptobyte"
    12  )
    13  
    14  var _ Extension = &GREASEExtension{}
    15  
    16  type GREASEExtension struct {
    17  	Id   uint16
    18  	Data cryptobyte.String
    19  }
    20  
    21  func (extension *GREASEExtension) ExtensionId() uint16 {
    22  	return extension.Id
    23  }
    24  
    25  func (*GREASEExtension) NegotiatedVersion(vers uint16) {}
    26  
    27  func (*GREASEExtension) Negotiate(messageType uint8) bool {
    28  	return false
    29  }
    30  func (extension *GREASEExtension) Marshal(messageType uint8, b *cryptobyte.Builder) {
    31  	b.AddBytes(extension.Data)
    32  }
    33  
    34  func (extension *GREASEExtension) Len(messageType uint8) int {
    35  	return len(extension.Data)
    36  }
    37  
    38  func (extension *GREASEExtension) Unmarshal(messageType uint8, b cryptobyte.String) bool {
    39  	extension.Data = b
    40  	return true
    41  }
    42  
    43  func (extension *GREASEExtension) Clone() Extension {
    44  	return &GREASEExtension{Id: extension.Id, Data: extension.Data}
    45  }
    46  
    47  // based on spec's GreaseStyle, GREASE_PLACEHOLDER may be replaced by another GREASE value
    48  // https://tools.ietf.org/html/draft-ietf-tls-grease-01
    49  const GREASE_PLACEHOLDER = 0x0a0a
    50  
    51  // will panic if ssl_grease_last_index[index] is out of bounds.
    52  func (c *Conn) GREASE() uint16 {
    53  	grease_bytes := make([]byte, 2)
    54  	// GREASE value is back from deterministic to random.
    55  
    56  	_, err := io.ReadFull(c.config.rand(), grease_bytes)
    57  	if err != nil {
    58  		return GREASE_PLACEHOLDER
    59  	}
    60  
    61  	ret := binary.LittleEndian.Uint16(grease_bytes)
    62  	/* This generates a random value of the form 0xωaωa, for all 0 ≤ ω < 16. */
    63  	ret = (ret & 0xf0) | 0x0a
    64  	ret |= ret << 8
    65  	return ret
    66  }
    67  
    68  func IsGREASE(v uint16) bool {
    69  	// First byte is same as second byte
    70  	// and lowest nibble is 0xa
    71  	return ((v >> 8) == v&0xff) && v&0xf == 0xa
    72  }