| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 | 
							- // Copyright (c) 2018, Open Systems AG. All rights reserved.
 
- //
 
- // Use of this source code is governed by a BSD-style license
 
- // that can be found in the LICENSE file in the root of the source
 
- // tree.
 
- package ja3
 
- import (
 
- 	"crypto/md5"
 
- 	"encoding/hex"
 
- 	"golang.org/x/exp/slices"
 
- )
 
- type ClientHello struct {
 
- 	Version             uint16
 
- 	CipherSuites        []uint16
 
- 	Extensions          []uint16
 
- 	EllipticCurves      []uint16
 
- 	EllipticCurvePF     []uint8
 
- 	Versions            []uint16
 
- 	SignatureAlgorithms []uint16
 
- 	ServerName          string
 
- 	ja3ByteString       []byte
 
- 	ja3Hash             string
 
- }
 
- func (j *ClientHello) Equals(another *ClientHello, ignoreExtensionsSequence bool) bool {
 
- 	if j.Version != another.Version {
 
- 		return false
 
- 	}
 
- 	if !slices.Equal(j.CipherSuites, another.CipherSuites) {
 
- 		return false
 
- 	}
 
- 	if !ignoreExtensionsSequence && !slices.Equal(j.Extensions, another.Extensions) {
 
- 		return false
 
- 	}
 
- 	if ignoreExtensionsSequence && !slices.Equal(j.Extensions, another.sortedExtensions()) {
 
- 		return false
 
- 	}
 
- 	if !slices.Equal(j.EllipticCurves, another.EllipticCurves) {
 
- 		return false
 
- 	}
 
- 	if !slices.Equal(j.EllipticCurvePF, another.EllipticCurvePF) {
 
- 		return false
 
- 	}
 
- 	if !slices.Equal(j.SignatureAlgorithms, another.SignatureAlgorithms) {
 
- 		return false
 
- 	}
 
- 	return true
 
- }
 
- func (j *ClientHello) sortedExtensions() []uint16 {
 
- 	extensions := make([]uint16, len(j.Extensions))
 
- 	copy(extensions, j.Extensions)
 
- 	slices.Sort(extensions)
 
- 	return extensions
 
- }
 
- func Compute(payload []byte) (*ClientHello, error) {
 
- 	ja3 := ClientHello{}
 
- 	err := ja3.parseSegment(payload)
 
- 	return &ja3, err
 
- }
 
- func (j *ClientHello) String() string {
 
- 	if j.ja3ByteString == nil {
 
- 		j.marshalJA3()
 
- 	}
 
- 	return string(j.ja3ByteString)
 
- }
 
- func (j *ClientHello) Hash() string {
 
- 	if j.ja3ByteString == nil {
 
- 		j.marshalJA3()
 
- 	}
 
- 	if j.ja3Hash == "" {
 
- 		h := md5.Sum(j.ja3ByteString)
 
- 		j.ja3Hash = hex.EncodeToString(h[:])
 
- 	}
 
- 	return j.ja3Hash
 
- }
 
 
  |