Initial import
This commit is contained in:
64
cmd/protodial/main.go
Normal file
64
cmd/protodial/main.go
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"git.maze.io/go/dpi/protocol"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
acceptFlag := flag.String("accept", "", "comma separated list of accepted protocols")
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
if flag.NArg() != 2 {
|
||||||
|
fmt.Fprintf(os.Stderr, "Usage: %s <host> <port>\n", os.Args[0])
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
accept := make(map[string]bool)
|
||||||
|
acceptFlags := strings.Split(*acceptFlag, ",")
|
||||||
|
if len(acceptFlags) == 0 {
|
||||||
|
fmt.Fprintln(os.Stderr, "No -accept was provided, refusing all protocols!")
|
||||||
|
} else {
|
||||||
|
for _, proto := range acceptFlags {
|
||||||
|
accept[proto] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c, err := net.Dial("tcp", net.JoinHostPort(flag.Arg(0), flag.Arg(1)))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
c = protocol.Limit(c, func(dir protocol.Direction, p *protocol.Protocol) error {
|
||||||
|
if p == nil {
|
||||||
|
return errors.New("No protocol detected")
|
||||||
|
}
|
||||||
|
if !accept[p.Name] {
|
||||||
|
return fmt.Errorf("Protocol %s is not accepted", p.Name)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(os.Stderr, "Accepting protocol %s version %s initiated by %s\n",
|
||||||
|
p.Name, p.Version, dir)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
defer c.Close()
|
||||||
|
|
||||||
|
var wait sync.WaitGroup
|
||||||
|
wait.Go(func() { multiplex(c, os.Stdin) })
|
||||||
|
wait.Go(func() { multiplex(os.Stdout, c) })
|
||||||
|
wait.Wait()
|
||||||
|
}
|
||||||
|
|
||||||
|
func multiplex(w io.Writer, r io.Reader) {
|
||||||
|
if _, err := io.Copy(w, r); err != nil && !errors.Is(err, io.EOF) {
|
||||||
|
log.Fatalln("Copy terminated:", err)
|
||||||
|
}
|
||||||
|
}
|
89
cmd/protoproxy/main.go
Normal file
89
cmd/protoproxy/main.go
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"flag"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"net"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.maze.io/go/dpi/protocol"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
listenFlag := flag.String("listen", "localhost:4080", "proxy listen address")
|
||||||
|
targetFlag := flag.String("target", "localhost:22", "proxy target address")
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
l, err := net.Listen("tcp", *listenFlag)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("listen error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("listening on %s", l.Addr())
|
||||||
|
for {
|
||||||
|
c, err := l.Accept()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln("accept error:", err)
|
||||||
|
}
|
||||||
|
go proxy(c, *targetFlag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func proxy(client net.Conn, target string) {
|
||||||
|
log.Printf("new connection from %s", client.RemoteAddr())
|
||||||
|
|
||||||
|
// Hangup client if we return
|
||||||
|
defer func() {
|
||||||
|
log.Printf("closing connection to %s: %v", client.RemoteAddr(), client.Close())
|
||||||
|
}()
|
||||||
|
|
||||||
|
log.Printf("dialing %s", target)
|
||||||
|
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
|
var dialer net.Dialer
|
||||||
|
|
||||||
|
server, err := dialer.DialContext(ctx, "tcp", target)
|
||||||
|
if err != nil {
|
||||||
|
cancel()
|
||||||
|
log.Printf("error connecting to %s: %v", target, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cancel()
|
||||||
|
|
||||||
|
// Hangup server if we return
|
||||||
|
defer func() {
|
||||||
|
log.Printf("closing connection to %s: %v", server.RemoteAddr(), server.Close())
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Setup interceptor and wrap the client and server connections.
|
||||||
|
interceptor := protocol.NewInterceptor()
|
||||||
|
client = interceptor.Client(client)
|
||||||
|
server = interceptor.Server(server)
|
||||||
|
|
||||||
|
// Request a return channel and start the detection before doing anything
|
||||||
|
// else with the client and server connections.
|
||||||
|
intercepted := interceptor.Detect(10 * time.Second)
|
||||||
|
|
||||||
|
log.Printf("client %s connected to %s; proxying", client.RemoteAddr(), server.RemoteAddr())
|
||||||
|
|
||||||
|
// Create a wait group and copy between client and server bidirectionally,
|
||||||
|
// either side needs to generate data for the detection to work.
|
||||||
|
var group sync.WaitGroup
|
||||||
|
group.Go(func() { io.Copy(client, server) })
|
||||||
|
group.Go(func() { io.Copy(server, client) })
|
||||||
|
|
||||||
|
// Wait until the interceptor produces data.
|
||||||
|
result := <-intercepted
|
||||||
|
if result.Error != nil {
|
||||||
|
log.Printf("protocol detection failed: %v", result.Error)
|
||||||
|
} else {
|
||||||
|
log.Printf("detected protocol %s version %s initiated by %s",
|
||||||
|
result.Protocol.Name, result.Protocol.Version, result.Direction)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for the multiplexing to finish.
|
||||||
|
group.Wait()
|
||||||
|
}
|
2
doc.go
Normal file
2
doc.go
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
// Package dpi contains helpers for performing deep packet inspection.
|
||||||
|
package dpi
|
26
error.go
Normal file
26
error.go
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package dpi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrInvalid = errors.New("invalid")
|
||||||
|
)
|
||||||
|
|
||||||
|
type DecodeError struct {
|
||||||
|
Reason string
|
||||||
|
Err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (err DecodeError) Error() string {
|
||||||
|
if err.Reason != "" {
|
||||||
|
return fmt.Sprintf("dpi: %s: %v", err.Reason, err.Err.Error())
|
||||||
|
}
|
||||||
|
return err.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (err DecodeError) Unwrap() error {
|
||||||
|
return err.Err
|
||||||
|
}
|
5
go.mod
Normal file
5
go.mod
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
module git.maze.io/go/dpi
|
||||||
|
|
||||||
|
go 1.25
|
||||||
|
|
||||||
|
require golang.org/x/crypto v0.42.0 // indirect
|
2
go.sum
Normal file
2
go.sum
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI=
|
||||||
|
golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8=
|
113
protocol/detect.go
Normal file
113
protocol/detect.go
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
package protocol
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Strict mode requires a full, compliant packet to be captured. This is only
|
||||||
|
// implemented by some detectors.
|
||||||
|
var Strict bool
|
||||||
|
|
||||||
|
// Common errors.
|
||||||
|
var (
|
||||||
|
ErrTimeout = errors.New("timeout")
|
||||||
|
ErrUnknown = errors.New("unknown protocol")
|
||||||
|
)
|
||||||
|
|
||||||
|
// Direction indicates the communcation direction.
|
||||||
|
type Direction int
|
||||||
|
|
||||||
|
// Directions supported by this package.
|
||||||
|
const (
|
||||||
|
Unknown Direction = iota
|
||||||
|
Client
|
||||||
|
Server
|
||||||
|
Both
|
||||||
|
)
|
||||||
|
|
||||||
|
func (dir Direction) Contains(other Direction) bool {
|
||||||
|
switch dir {
|
||||||
|
case Client:
|
||||||
|
return other == Client || other == Both
|
||||||
|
case Server:
|
||||||
|
return other == Server || other == Both
|
||||||
|
case Both:
|
||||||
|
return other == Client || other == Server
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var directionName = map[Direction]string{
|
||||||
|
Client: "client",
|
||||||
|
Server: "server",
|
||||||
|
Both: "both",
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dir Direction) String() string {
|
||||||
|
if s, ok := directionName[dir]; ok {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("invalid (%d)", int(dir))
|
||||||
|
}
|
||||||
|
|
||||||
|
type format struct {
|
||||||
|
dir Direction
|
||||||
|
magic string
|
||||||
|
detect DetectFunc
|
||||||
|
}
|
||||||
|
|
||||||
|
// Formats is the list of registered formats.
|
||||||
|
var (
|
||||||
|
formatsMu sync.Mutex
|
||||||
|
atomicFormats atomic.Value
|
||||||
|
)
|
||||||
|
|
||||||
|
type DetectFunc func(Direction, []byte) *Protocol
|
||||||
|
|
||||||
|
func Register(dir Direction, magic string, detect DetectFunc) {
|
||||||
|
formatsMu.Lock()
|
||||||
|
formats, _ := atomicFormats.Load().([]format)
|
||||||
|
atomicFormats.Store(append(formats, format{dir, magic, detect}))
|
||||||
|
formatsMu.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
func matchMagic(magic string, data []byte) bool {
|
||||||
|
// Empty magic means the detector will always run.
|
||||||
|
if len(magic) == 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// The buffer should contain at least the same number of bytes
|
||||||
|
// as our magic.
|
||||||
|
if len(data) < len(magic) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Match bytes in magic with bytes in data.
|
||||||
|
for i, b := range []byte(magic) {
|
||||||
|
if b != '?' && data[i] != b {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detect a protocol based on the provided data.
|
||||||
|
func Detect(dir Direction, data []byte) (*Protocol, error) {
|
||||||
|
formats, _ := atomicFormats.Load().([]format)
|
||||||
|
for _, f := range formats {
|
||||||
|
if f.dir.Contains(dir) {
|
||||||
|
// Check the buffer to see if we have sufficient bytes
|
||||||
|
if matchMagic(f.magic, data) {
|
||||||
|
if p := f.detect(dir, data); p != nil {
|
||||||
|
return p, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, ErrUnknown
|
||||||
|
}
|
94
protocol/detect_http.go
Normal file
94
protocol/detect_http.go
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
package protocol
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
Register(Client, "", detectHTTPRequest)
|
||||||
|
Register(Server, "HTTP/?.", detectHTTPResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
func detectHTTPRequest(dir Direction, data []byte) *Protocol {
|
||||||
|
// A minimal request "GET / HTTP/1.0\r\n" is > 8 bytes.
|
||||||
|
if len(data) < 8 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if Strict {
|
||||||
|
var (
|
||||||
|
b = append(data, '\r', '\n')
|
||||||
|
r = bufio.NewReader(bytes.NewReader(b))
|
||||||
|
)
|
||||||
|
if request, err := http.ReadRequest(r); err == nil {
|
||||||
|
return &Protocol{
|
||||||
|
Name: ProtocolHTTP,
|
||||||
|
Version: Version{
|
||||||
|
Major: request.ProtoMajor,
|
||||||
|
Minor: request.ProtoMinor,
|
||||||
|
Patch: -1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
r.Reset(bytes.NewReader(b))
|
||||||
|
if response, err := http.ReadResponse(r, nil); err == nil {
|
||||||
|
return &Protocol{
|
||||||
|
Name: ProtocolHTTP,
|
||||||
|
Version: Version{
|
||||||
|
Major: response.ProtoMajor,
|
||||||
|
Minor: response.ProtoMinor,
|
||||||
|
Patch: -1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
crlfIndex := bytes.IndexFunc(data, func(r rune) bool {
|
||||||
|
return r == '\r' || r == '\n'
|
||||||
|
})
|
||||||
|
if crlfIndex == -1 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// A request has three, space-separated parts.
|
||||||
|
part := bytes.Split(data[:crlfIndex], []byte(" "))
|
||||||
|
if len(part) != 3 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// The last part starts with "HTTP/".
|
||||||
|
if !bytes.HasPrefix(part[2], []byte("HTTP/1")) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var version = Version{Patch: -1}
|
||||||
|
fmt.Sscanf(string(part[2]), "HTTP/%d.%d ", &version.Major, &version.Minor)
|
||||||
|
|
||||||
|
return &Protocol{
|
||||||
|
Name: ProtocolHTTP,
|
||||||
|
Version: version,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func detectHTTPResponse(dir Direction, data []byte) *Protocol {
|
||||||
|
if !dir.Contains(Server) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// A minimal response "HTTP/1.0 200 OK\r\n" is > 8 bytes.
|
||||||
|
if len(data) < 8 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var version = Version{Patch: -1}
|
||||||
|
fmt.Sscanf(string(data), "HTTP/%d.%d ", &version.Major, &version.Minor)
|
||||||
|
|
||||||
|
return &Protocol{
|
||||||
|
Name: ProtocolHTTP,
|
||||||
|
Version: version,
|
||||||
|
}
|
||||||
|
}
|
154
protocol/detect_http_test.go
Normal file
154
protocol/detect_http_test.go
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
package protocol
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestDetectHTTPRequest(t *testing.T) {
|
||||||
|
atomicFormats.Store([]format{{Client, "", detectHTTPRequest}})
|
||||||
|
|
||||||
|
// A valid HTTP/1.0 GET request
|
||||||
|
http10Request := []byte("GET /old-page.html HTTP/1.0\r\nUser-Agent: NCSA_Mosaic/1.0\r\n\r\n")
|
||||||
|
|
||||||
|
// A valid HTTP/1.1 GET request
|
||||||
|
getRequest := []byte("GET /resource/item?id=123 HTTP/1.1\r\nHost: example.com\r\n\r\n")
|
||||||
|
|
||||||
|
// An invalid HTTP request
|
||||||
|
sshBanner := []byte("SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.4\r\n")
|
||||||
|
|
||||||
|
defer func() { Strict = false }()
|
||||||
|
for _, strict := range []bool{false, true} {
|
||||||
|
Strict = strict
|
||||||
|
|
||||||
|
name := "loose"
|
||||||
|
if strict {
|
||||||
|
name = "strict"
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
t.Run("HTTP/1.0 GET", func(t *testing.T) {
|
||||||
|
p, err := Detect(Client, http10Request)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t.Logf("detected %s version %s", p.Name, p.Version)
|
||||||
|
if p.Name != ProtocolHTTP {
|
||||||
|
t.Fatalf("expected http protocol, got %s", p.Name)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("HTTP/1.1 GET", func(t *testing.T) {
|
||||||
|
p, err := Detect(Client, getRequest)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t.Logf("detected %s version %s", p.Name, p.Version)
|
||||||
|
if p.Name != ProtocolHTTP {
|
||||||
|
t.Fatalf("expected http protocol, got %s", p.Name)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Invalid SSH", func(t *testing.T) {
|
||||||
|
_, err := Detect(Server, sshBanner)
|
||||||
|
if !errors.Is(err, ErrUnknown) {
|
||||||
|
t.Fatalf("expected unknown format, got error %T: %q", err, err)
|
||||||
|
} else {
|
||||||
|
t.Logf("error %q, as expected", err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDetectHTTPResponse(t *testing.T) {
|
||||||
|
atomicFormats.Store([]format{{Server, "HTTP/?.? ", detectHTTPResponse}})
|
||||||
|
|
||||||
|
// A valid HTTP/1.0 403 Forbidden response
|
||||||
|
http10Response := []byte("HTTP/1.0 403 Forbidden\r\nServer: CERN/3.0\r\n\r\n")
|
||||||
|
|
||||||
|
// A valid HTTP/1.1 200 OK response
|
||||||
|
responseOK := []byte("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<html>...</html>")
|
||||||
|
|
||||||
|
// A valid HTTP/1.1 404 Not Found response
|
||||||
|
responseNotFound := []byte("HTTP/1.1 404 Not Found\r\nContent-Length: 0\r\n\r\n")
|
||||||
|
|
||||||
|
// An invalid HTTP GET request
|
||||||
|
getRequest := []byte("GET /resource/item?id=123 HTTP/1.1\r\nHost: example.com\r\n\r\n")
|
||||||
|
|
||||||
|
// An invalid banner (SSH)
|
||||||
|
sshBanner := []byte("SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.4\r\n")
|
||||||
|
|
||||||
|
defer func() { Strict = false }()
|
||||||
|
for _, strict := range []bool{false, true} {
|
||||||
|
Strict = strict
|
||||||
|
|
||||||
|
name := "loose"
|
||||||
|
if strict {
|
||||||
|
name = "strict"
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
t.Run("HTTP/1.0 403", func(t *testing.T) {
|
||||||
|
p, err := Detect(Server, http10Response)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t.Logf("detected %s version %s", p.Name, p.Version)
|
||||||
|
if p.Name != ProtocolHTTP {
|
||||||
|
t.Fatalf("expected http protocol, got %s", p.Name)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("HTTP/1.1 200", func(t *testing.T) {
|
||||||
|
p, err := Detect(Server, responseOK)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t.Logf("detected %s version %s", p.Name, p.Version)
|
||||||
|
if p.Name != ProtocolHTTP {
|
||||||
|
t.Fatalf("expected http protocol, got %s", p.Name)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("HTTP/1.1 404", func(t *testing.T) {
|
||||||
|
p, err := Detect(Server, responseNotFound)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t.Logf("detected %s version %s", p.Name, p.Version)
|
||||||
|
if p.Name != ProtocolHTTP {
|
||||||
|
t.Fatalf("expected http protocol, got %s", p.Name)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Invalid HTTP/1.1 GET", func(t *testing.T) {
|
||||||
|
_, err := Detect(Server, getRequest)
|
||||||
|
if !errors.Is(err, ErrUnknown) {
|
||||||
|
t.Fatalf("expected unknown format, got error %T: %q", err, err)
|
||||||
|
} else {
|
||||||
|
t.Logf("error %q, as expected", err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Invalid SSH", func(t *testing.T) {
|
||||||
|
_, err := Detect(Server, sshBanner)
|
||||||
|
if !errors.Is(err, ErrUnknown) {
|
||||||
|
t.Fatalf("expected unknown format, got error %T: %q", err, err)
|
||||||
|
} else {
|
||||||
|
t.Logf("error %q, as expected", err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
51
protocol/detect_mysql.go
Normal file
51
protocol/detect_mysql.go
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
package protocol
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
Register(Server, "\x0a", detectMySQL)
|
||||||
|
}
|
||||||
|
|
||||||
|
func detectMySQL(dir Direction, data []byte) *Protocol {
|
||||||
|
if len(data) < 7 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// The first byte of the handshake packet is the protocol version.
|
||||||
|
// For MySQL, this is 10 (0x0A).
|
||||||
|
if data[0] != 0x0A {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// After the protocol version, there is a null-terminated server version string.
|
||||||
|
// We search for the null byte starting from the second byte (index 1).
|
||||||
|
nullIndex := bytes.IndexByte(data[1:], 0x00)
|
||||||
|
|
||||||
|
// If no null byte is found, it's not a valid banner.
|
||||||
|
if nullIndex == -1 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// The position of the null byte is relative to the start of the whole slice.
|
||||||
|
// It's 1 (for the protocol byte) + nullIndex.
|
||||||
|
serverVersionEndPos := 1 + nullIndex
|
||||||
|
|
||||||
|
// After the null-terminated version string, there must be at least 4 bytes
|
||||||
|
// for the connection ID, plus more data for capabilities, auth, etc.
|
||||||
|
// We'll check for the 4-byte connection ID as a minimum requirement.
|
||||||
|
const connectionIDLength = 4
|
||||||
|
if len(data) < serverVersionEndPos+1+connectionIDLength {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var version Version
|
||||||
|
fmt.Sscanf(string(data[1:serverVersionEndPos]), "%d.%d.%d-%s", &version.Major, &version.Minor, &version.Patch, &version.Extra)
|
||||||
|
|
||||||
|
return &Protocol{
|
||||||
|
Name: ProtocolMySQL,
|
||||||
|
Version: version,
|
||||||
|
}
|
||||||
|
}
|
82
protocol/detect_mysql_test.go
Normal file
82
protocol/detect_mysql_test.go
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
package protocol
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestDetectMySQL(t *testing.T) {
|
||||||
|
atomicFormats.Store([]format{{Server, "\x0a", detectMySQL}})
|
||||||
|
|
||||||
|
// 1. A valid MySQL 8.0 banner
|
||||||
|
mysql8Banner := []byte{
|
||||||
|
0x0a, 0x38, 0x2e, 0x30, 0x2e, 0x33, 0x32, 0x00, 0x0d, 0x00, 0x00, 0x00,
|
||||||
|
0x04, 0x5a, 0x56, 0x5f, 0x3e, 0x6e, 0x76, 0x27, 0x00, 0xff, 0xff, 0xff,
|
||||||
|
0x02, 0x00, 0xff, 0xc7, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x63, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x5f, 0x73,
|
||||||
|
0x68, 0x61, 0x32, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x00,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. A valid MariaDB banner (protocol-compatible)
|
||||||
|
mariaDBBanner := []byte{
|
||||||
|
0x0a, 0x35, 0x2e, 0x35, 0x2e, 0x35, 0x2d, 0x31, 0x30, 0x2e, 0x36, 0x2e,
|
||||||
|
0x35, 0x2d, 0x4d, 0x61, 0x72, 0x69, 0x61, 0x44, 0x42, 0x2d, 0x6c, 0x6f,
|
||||||
|
0x67, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x4e, 0x5c, 0x32, 0x7b, 0x45, 0x3b,
|
||||||
|
0x40, 0x60, 0x00, 0xff, 0xf7, 0x08, 0x02, 0x00, 0xff, 0x81, 0x15, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x79, 0x73,
|
||||||
|
0x71, 0x6c, 0x5f, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x70, 0x61,
|
||||||
|
0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x00,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. An invalid banner (e.g., an HTTP request)
|
||||||
|
httpBanner := []byte("GET / HTTP/1.1\r\nHost: example.com\r\n\r\n")
|
||||||
|
|
||||||
|
// 4. A short, invalid slice
|
||||||
|
shortSlice := []byte{0x0a, 0x31, 0x32, 0x33}
|
||||||
|
|
||||||
|
// 5. A slice that starts correctly but is malformed (no null terminator)
|
||||||
|
malformedSlice := []byte{0x0a, 0x38, 0x2e, 0x30, 0x2e, 0x30, 0x01, 0x02, 0x03, 0x04, 0x05}
|
||||||
|
|
||||||
|
t.Run("MySQL 8", func(t *testing.T) {
|
||||||
|
p, _ := Detect(Server, mysql8Banner)
|
||||||
|
if p == nil {
|
||||||
|
t.Fatal("expected MySQL protocol, got nil")
|
||||||
|
}
|
||||||
|
t.Logf("detected %s version %s", p.Name, p.Version)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("MariaDB", func(t *testing.T) {
|
||||||
|
p, _ := Detect(Server, mariaDBBanner)
|
||||||
|
if p == nil {
|
||||||
|
t.Fatal("expected MySQL protocol, got nil")
|
||||||
|
}
|
||||||
|
t.Logf("detected %s version %s", p.Name, p.Version)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Invalid HTTP", func(t *testing.T) {
|
||||||
|
_, err := Detect(Server, httpBanner)
|
||||||
|
if !errors.Is(err, ErrUnknown) {
|
||||||
|
t.Fatalf("expected unknown format, got error %T: %q", err, err)
|
||||||
|
} else {
|
||||||
|
t.Logf("error %q, as expected", err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Too short", func(t *testing.T) {
|
||||||
|
_, err := Detect(Server, shortSlice)
|
||||||
|
if !errors.Is(err, ErrUnknown) {
|
||||||
|
t.Fatalf("expected unknown format, got error %T: %q", err, err)
|
||||||
|
} else {
|
||||||
|
t.Logf("error %q, as expected", err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Malformed", func(t *testing.T) {
|
||||||
|
_, err := Detect(Server, malformedSlice)
|
||||||
|
if !errors.Is(err, ErrUnknown) {
|
||||||
|
t.Fatalf("expected unknown format, got error %T: %q", err, err)
|
||||||
|
} else {
|
||||||
|
t.Logf("error %q, as expected", err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
70
protocol/detect_postgres.go
Normal file
70
protocol/detect_postgres.go
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
package protocol
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
registerPostgreSQL()
|
||||||
|
}
|
||||||
|
|
||||||
|
func registerPostgreSQL() {
|
||||||
|
Register(Server, "R\x00???", detectPostgreSQLServer) // Authentication request
|
||||||
|
Register(Server, "K\x00???", detectPostgreSQLServer) // BackendKeyData
|
||||||
|
Register(Server, "S\x00???", detectPostgreSQLServer) // ParameterStatus
|
||||||
|
Register(Server, "Z\x00???", detectPostgreSQLServer) // ReadyForQuery
|
||||||
|
Register(Server, "E\x00???", detectPostgreSQLServer) // ErrorResponse
|
||||||
|
Register(Server, "N\x00???", detectPostgreSQLServer) // NoticeResponse
|
||||||
|
Register(Client, "????\x00\x02\x00\x00", detectPostgreSQLClient) // Startup packet, protocol 2.0
|
||||||
|
Register(Client, "????\x00\x03\x00\x00", detectPostgreSQLClient) // Startup packet, protocol 3.0
|
||||||
|
}
|
||||||
|
|
||||||
|
func detectPostgreSQLClient(dir Direction, data []byte) *Protocol {
|
||||||
|
// A client startup message needs at least 8 bytes (length + protocol version).
|
||||||
|
if len(data) < 8 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
length := int(binary.BigEndian.Uint32(data[0:]))
|
||||||
|
if len(data) != length {
|
||||||
|
log.Printf("not postgres %q: %d != %d", data, len(data), length)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
major := int(binary.BigEndian.Uint16(data[4:]))
|
||||||
|
minor := int(binary.BigEndian.Uint16(data[6:]))
|
||||||
|
if major == 2 || major == 3 {
|
||||||
|
return &Protocol{
|
||||||
|
Name: ProtocolPostgreSQL,
|
||||||
|
Version: Version{
|
||||||
|
Major: major,
|
||||||
|
Minor: minor,
|
||||||
|
Patch: -1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func detectPostgreSQLServer(dir Direction, data []byte) *Protocol {
|
||||||
|
// A server message needs at least 5 bytes (type + length).
|
||||||
|
if len(data) < 5 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// All server messages (and subsequent client messages) are tagged with a single-byte type.
|
||||||
|
firstByte := data[0]
|
||||||
|
switch firstByte {
|
||||||
|
case 'R', // Authentication request
|
||||||
|
'K', // BackendKeyData
|
||||||
|
'S', // ParameterStatus
|
||||||
|
'Z', // ReadyForQuery
|
||||||
|
'E', // ErrorResponse
|
||||||
|
'N': // NoticeResponse
|
||||||
|
return &Protocol{Name: ProtocolPostgreSQL}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
94
protocol/detect_postgres_test.go
Normal file
94
protocol/detect_postgres_test.go
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
package protocol
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestDetectPostgreSQLClient(t *testing.T) {
|
||||||
|
atomicFormats.Store([]format{})
|
||||||
|
registerPostgreSQL()
|
||||||
|
|
||||||
|
// 1. A valid PostgreSQL client startup message
|
||||||
|
// Format: len (4b), proto (4b), params (n-bytes)
|
||||||
|
// Here, user=mazeio, database=test
|
||||||
|
// The message is: "user\0mazeio\0database\0test\0\0"
|
||||||
|
// Total length: 4 (len) + 4 (proto) + 27 (params) = 35 (0x23)
|
||||||
|
pgClientStartup := []byte{
|
||||||
|
0x00, 0x00, 0x00, 0x23, // Length: 35
|
||||||
|
0x00, 0x03, 0x00, 0x00, // Protocol Version 3.0
|
||||||
|
'u', 's', 'e', 'r', 0x00, 'm', 'a', 'z', 'e', 'i', 'o', 0x00,
|
||||||
|
'd', 'a', 't', 'a', 'b', 'a', 's', 'e', 0x00, 't', 'e', 's', 't', 0x00, 0x00,
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("Protocol 3.0", func(t *testing.T) {
|
||||||
|
p, err := Detect(Client, pgClientStartup)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t.Logf("detected %s version %s", p.Name, p.Version)
|
||||||
|
if p.Name != ProtocolPostgreSQL {
|
||||||
|
t.Fatalf("expected postgres protocol, got %s", p.Name)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDetectPostgreSQLServer(t *testing.T) {
|
||||||
|
atomicFormats.Store([]format{})
|
||||||
|
registerPostgreSQL()
|
||||||
|
|
||||||
|
// A valid PostgreSQL server AuthenticationOk response
|
||||||
|
// Format: type (1b), len (4b), content (4b)
|
||||||
|
pgServerAuthOK := []byte{
|
||||||
|
'R', // Type: Authentication
|
||||||
|
0x00, 0x00, 0x00, 0x08, // Length: 8
|
||||||
|
0x00, 0x00, 0x00, 0x00, // Auth OK (0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// A valid PostgreSQL server ErrorResponse
|
||||||
|
pgServerError := []byte{
|
||||||
|
'E', // Type: ErrorResponse
|
||||||
|
0x00, 0x00, 0x00, 0x31, // Length
|
||||||
|
'S', 'E', 'R', 'R', 'O', 'R', 0x00, // ... and so on
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invalid data (HTTP GET request)
|
||||||
|
httpBanner := []byte("GET / HTTP/1.1\r\nHost: example.com\r\n\r\n")
|
||||||
|
|
||||||
|
t.Run("AuthenticationOk", func(t *testing.T) {
|
||||||
|
p, err := Detect(Server, pgServerAuthOK)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t.Logf("detected %s version %s", p.Name, p.Version)
|
||||||
|
if p.Name != ProtocolPostgreSQL {
|
||||||
|
t.Fatalf("expected postgres protocol, got %s", p.Name)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("ErrorResponse", func(t *testing.T) {
|
||||||
|
p, err := Detect(Server, pgServerError)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t.Logf("detected %s version %s", p.Name, p.Version)
|
||||||
|
if p.Name != ProtocolPostgreSQL {
|
||||||
|
t.Fatalf("expected postgres protocol, got %s", p.Name)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Invalid HTTP", func(t *testing.T) {
|
||||||
|
_, err := Detect(Server, httpBanner)
|
||||||
|
if !errors.Is(err, ErrUnknown) {
|
||||||
|
t.Fatalf("expected unknown format, got error %T: %q", err, err)
|
||||||
|
} else {
|
||||||
|
t.Logf("error %q, as expected", err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
51
protocol/detect_ssh.go
Normal file
51
protocol/detect_ssh.go
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
package protocol
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
)
|
||||||
|
|
||||||
|
// The required prefix for the SSH protocol identification line.
|
||||||
|
const (
|
||||||
|
ssh199Prefix = "SSH-1.99-"
|
||||||
|
ssh20Prefix = "SSH-2.0-"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
Register(Both, "", detectSSH)
|
||||||
|
}
|
||||||
|
|
||||||
|
func detectSSH(dir Direction, data []byte) *Protocol {
|
||||||
|
// The data must be at least as long as the prefix itself.
|
||||||
|
if len(data) < len(ssh20Prefix) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// The protocol allows for pre-banner text, so we have to check all lines.
|
||||||
|
for _, line := range bytes.Split(data, []byte{'\n'}) {
|
||||||
|
line = bytes.TrimSuffix(line, []byte{'\r'})
|
||||||
|
if bytes.HasPrefix(line, []byte(ssh20Prefix)) {
|
||||||
|
return &Protocol{
|
||||||
|
Name: ProtocolSSH,
|
||||||
|
Version: Version{
|
||||||
|
Major: 2,
|
||||||
|
Minor: 0,
|
||||||
|
Patch: -1,
|
||||||
|
Extra: string(line[len(ssh20Prefix):]),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if bytes.HasPrefix(line, []byte(ssh199Prefix)) {
|
||||||
|
return &Protocol{
|
||||||
|
Name: ProtocolSSH,
|
||||||
|
Version: Version{
|
||||||
|
Major: 1,
|
||||||
|
Minor: 99,
|
||||||
|
Patch: -1,
|
||||||
|
Extra: string(line[len(ssh20Prefix):]),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
103
protocol/detect_ssh_test.go
Normal file
103
protocol/detect_ssh_test.go
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
package protocol
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestDetectSSH(t *testing.T) {
|
||||||
|
atomicFormats.Store([]format{{Both, "", detectSSH}})
|
||||||
|
|
||||||
|
// 1. A standard OpenSSH banner
|
||||||
|
openSSHBanner := []byte("SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.4\r\n")
|
||||||
|
|
||||||
|
// 2. An SSH banner with a pre-banner legal notice
|
||||||
|
preBannerSSH := []byte(
|
||||||
|
"*******************************************************************\r\n" +
|
||||||
|
"* W A R N I N G *\r\n" +
|
||||||
|
"* This system is for the use of authorized users only. *\r\n" +
|
||||||
|
"*******************************************************************\r\n" +
|
||||||
|
"SSH-2.0-OpenSSH_7.6p1\r\n",
|
||||||
|
)
|
||||||
|
|
||||||
|
// 3. A different SSH implementation (Dropbear)
|
||||||
|
dropbearBanner := []byte("SSH-2.0-dropbear_2020.81\r\n")
|
||||||
|
|
||||||
|
// 4. An invalid banner (e.g., the MySQL banner from the previous example)
|
||||||
|
mysqlBanner := []byte{
|
||||||
|
0x0a, 0x38, 0x2e, 0x30, 0x2e, 0x33, 0x32, 0x00, 0x0d, 0x00, 0x00, 0x00,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. A simple HTTP request
|
||||||
|
httpBanner := []byte("GET / HTTP/1.1\r\nHost: example.com\r\n\r\n")
|
||||||
|
|
||||||
|
t.Run("OpenSSH client", func(t *testing.T) {
|
||||||
|
p, err := Detect(Server, openSSHBanner)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t.Logf("detected %s version %s", p.Name, p.Version)
|
||||||
|
if p.Name != ProtocolSSH {
|
||||||
|
t.Fatalf("expected ssh protocol, got %s", p.Name)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("OpenSSH server", func(t *testing.T) {
|
||||||
|
p, err := Detect(Server, openSSHBanner)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t.Logf("detected %s version %s", p.Name, p.Version)
|
||||||
|
if p.Name != ProtocolSSH {
|
||||||
|
t.Fatalf("expected ssh protocol, got %s", p.Name)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("OpenSSH server with banner", func(t *testing.T) {
|
||||||
|
p, err := Detect(Server, preBannerSSH)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t.Logf("detected %s version %s", p.Name, p.Version)
|
||||||
|
if p.Name != ProtocolSSH {
|
||||||
|
t.Fatalf("expected ssh protocol, got %s", p.Name)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Dropbear server", func(t *testing.T) {
|
||||||
|
p, err := Detect(Server, dropbearBanner)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t.Logf("detected %s version %s", p.Name, p.Version)
|
||||||
|
if p.Name != ProtocolSSH {
|
||||||
|
t.Fatalf("expected ssh protocol, got %s", p.Name)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Invalid MySQL banner", func(t *testing.T) {
|
||||||
|
_, err := Detect(Server, mysqlBanner)
|
||||||
|
if !errors.Is(err, ErrUnknown) {
|
||||||
|
t.Fatalf("expected unknown format, got error %T: %q", err, err)
|
||||||
|
} else {
|
||||||
|
t.Logf("error %q, as expected", err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Invalid HTTP banner", func(t *testing.T) {
|
||||||
|
_, err := Detect(Server, httpBanner)
|
||||||
|
if !errors.Is(err, ErrUnknown) {
|
||||||
|
t.Fatalf("expected unknown format, got error %T: %q", err, err)
|
||||||
|
} else {
|
||||||
|
t.Logf("error %q, as expected", err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
98
protocol/detect_tls.go
Normal file
98
protocol/detect_tls.go
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
package protocol
|
||||||
|
|
||||||
|
import (
|
||||||
|
"golang.org/x/crypto/cryptobyte"
|
||||||
|
|
||||||
|
"git.maze.io/go/dpi"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
registerTLS()
|
||||||
|
}
|
||||||
|
|
||||||
|
func registerTLS() {
|
||||||
|
Register(Both, "\x16\x03\x00", detectTLS) // SSLv3
|
||||||
|
Register(Both, "\x16\x03\x01", detectTLS) // TLSv1.0
|
||||||
|
Register(Both, "\x16\x03\x02", detectTLS) // TLSv1.1
|
||||||
|
Register(Both, "\x16\x03\x03", detectTLS) // TLSv1.2
|
||||||
|
}
|
||||||
|
|
||||||
|
func detectTLS(dir Direction, data []byte) *Protocol {
|
||||||
|
stream := cryptobyte.String(data)
|
||||||
|
|
||||||
|
// A TLS packet always has a content type (1 byte), version (2 bytes) and length (2 bytes).
|
||||||
|
if len(stream) < 5 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for TLS Handshake (type 22)
|
||||||
|
var header struct {
|
||||||
|
Type uint8
|
||||||
|
Version uint16
|
||||||
|
Length uint32
|
||||||
|
}
|
||||||
|
if !stream.ReadUint8(&header.Type) || header.Type != 0x16 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if !stream.ReadUint16(&header.Version) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if !stream.ReadUint24(&header.Length) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detected SSL/TLS version
|
||||||
|
var version dpi.TLSVersion
|
||||||
|
|
||||||
|
// Attempt to decode the full TLS Client Hello handshake
|
||||||
|
if version == 0 {
|
||||||
|
if hello, err := dpi.DecodeTLSClientHelloHandshake(data); err == nil {
|
||||||
|
version = hello.Version
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attempt to decode the full TLS Server Hello handshake
|
||||||
|
if version == 0 {
|
||||||
|
if hello, err := dpi.DecodeTLSServerHello(data); err == nil {
|
||||||
|
version = hello.Version
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attempt to decode at least the handshake protocol and version.
|
||||||
|
if version == 0 && !Strict {
|
||||||
|
var handshakeType uint8
|
||||||
|
if stream.ReadUint8(&handshakeType) && (handshakeType == 1 || handshakeType == 2) {
|
||||||
|
var (
|
||||||
|
length uint32
|
||||||
|
versionWord uint16
|
||||||
|
)
|
||||||
|
if stream.ReadUint24(&length) && stream.ReadUint16(&versionWord) {
|
||||||
|
version = dpi.TLSVersion(versionWord)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fall back to the version in the TLS record header, this is less accurate
|
||||||
|
if version == 0 && !Strict {
|
||||||
|
version = dpi.TLSVersion(header.Version)
|
||||||
|
}
|
||||||
|
|
||||||
|
// We're "multi protocol", in that SSL is its own protocol
|
||||||
|
if version == dpi.VersionSSL30 {
|
||||||
|
return &Protocol{
|
||||||
|
Name: ProtocolSSL,
|
||||||
|
Version: Version{Major: 3, Minor: 0, Patch: -1},
|
||||||
|
}
|
||||||
|
} else if version >= dpi.VersionTLS10 && version <= dpi.VersionTLS13 {
|
||||||
|
return &Protocol{
|
||||||
|
Name: ProtocolTLS,
|
||||||
|
Version: Version{Major: 1, Minor: int(uint8(version) - 1), Patch: -1},
|
||||||
|
}
|
||||||
|
} else if version >= dpi.VersionTLS13Draft && version <= dpi.VersionTLS13Draft23 {
|
||||||
|
return &Protocol{
|
||||||
|
Name: ProtocolTLS,
|
||||||
|
Version: Version{Major: 1, Minor: 3, Patch: -1},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
280
protocol/detect_tls_test.go
Normal file
280
protocol/detect_tls_test.go
Normal file
@@ -0,0 +1,280 @@
|
|||||||
|
package protocol
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/hex"
|
||||||
|
"errors"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestDetectTLS(t *testing.T) {
|
||||||
|
atomicFormats.Store([]format{})
|
||||||
|
registerTLS()
|
||||||
|
|
||||||
|
// A SSLv3 Client Hello
|
||||||
|
sslV3ClientHello := testMustDecodeHexString(`
|
||||||
|
16 03 00 00 51 01 00 00 4d 03
|
||||||
|
00 50 42 b2 29 1f cf 52 a0 94 87 05 e7 0b 63 08
|
||||||
|
12 a2 6c 59 f7 f5 72 2b 57 14 a7 07 95 cb ce e5
|
||||||
|
e4 00 00 26 00 04 00 05 00 2f 00 33 00 32 00 0a
|
||||||
|
fe ff 00 16 00 13 00 66 00 09 fe fe 00 15 00 12
|
||||||
|
00 03 00 08 00 06 00 14 00 11 01 00`)
|
||||||
|
|
||||||
|
// A synthesized TLS 1.1 ClientHello
|
||||||
|
tls11ClientHello := []byte{
|
||||||
|
// --- Record Layer (5 bytes) ---
|
||||||
|
0x16, // Content Type: Handshake (22)
|
||||||
|
0x03, 0x02, // Version: TLS 1.1 (Major=3, Minor=2)
|
||||||
|
0x00, 0x45, // Length of the handshake message below (69 bytes)
|
||||||
|
|
||||||
|
// --- Handshake Protocol: ClientHello (69 bytes) ---
|
||||||
|
0x01, // Handshake Type: ClientHello (1)
|
||||||
|
0x00, 0x00, 0x41, // Length of the rest of the message (65 bytes)
|
||||||
|
0x03, 0x02, // Client Version: TLS 1.1 (Major=3, Minor=2)
|
||||||
|
|
||||||
|
// Random (32 bytes):
|
||||||
|
// In TLS 1.1+, the entire 32 bytes are fully random.
|
||||||
|
// The timestamp structure from SSLv3 is removed.
|
||||||
|
0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
|
||||||
|
0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00,
|
||||||
|
0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
|
||||||
|
0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00,
|
||||||
|
|
||||||
|
// Session ID
|
||||||
|
0x00, // Session ID Length: 0 (new session)
|
||||||
|
|
||||||
|
// Cipher Suites
|
||||||
|
0x00, 0x04, // Cipher Suites Length: 4 bytes (2 suites)
|
||||||
|
0x00, 0x2F, // Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA
|
||||||
|
0x00, 0x35, // Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA
|
||||||
|
|
||||||
|
// Compression Methods
|
||||||
|
0x01, // Compression Methods Length: 1 byte
|
||||||
|
0x00, // Compression Method: NULL (0)
|
||||||
|
|
||||||
|
// --- Extensions (20 bytes) ---
|
||||||
|
0x00, 0x14, // Extensions Length: 20 bytes
|
||||||
|
// Extension: Server Name Indication (SNI)
|
||||||
|
0x00, 0x00, // Extension Type: server_name (0)
|
||||||
|
0x00, 0x10, // Extension Length: 16 bytes
|
||||||
|
0x00, 0x0E, // Server Name List Length: 14 bytes
|
||||||
|
0x00, // Server Name Type: host_name (0)
|
||||||
|
0x00, 0x0B, // Server Name Length: 11 bytes
|
||||||
|
// Server Name: "example.com"
|
||||||
|
'e', 'x', 'a', 'm', 'p', 'l', 'e', '.', 'c', 'o', 'm',
|
||||||
|
}
|
||||||
|
|
||||||
|
// A synthesized partial TLS 1.1 ClientHello
|
||||||
|
tls11ClientHelloPartial := []byte{
|
||||||
|
// --- Record Layer (5 bytes) ---
|
||||||
|
0x16, // Content Type: Handshake (22)
|
||||||
|
0x03, 0x02, // Version: TLS 1.1 (Major=3, Minor=2)
|
||||||
|
0x00, 0x45, // Length of the handshake message below (69 bytes)
|
||||||
|
|
||||||
|
// --- Handshake Protocol: ClientHello (69 bytes) ---
|
||||||
|
0x01, // Handshake Type: ClientHello (1)
|
||||||
|
0x00, 0x00, 0x41, // Length of the rest of the message (65 bytes)
|
||||||
|
0x03, 0x02, // Client Version: TLS 1.1 (Major=3, Minor=2)
|
||||||
|
}
|
||||||
|
|
||||||
|
// A synthesized TLSv1.2 ClientHello
|
||||||
|
tls12ClientHello := []byte{
|
||||||
|
// --- Record Layer (5 bytes) ---
|
||||||
|
0x16, // Content Type: Handshake (22)
|
||||||
|
0x03, 0x03, // Version: TLS 1.2 (Major=3, Minor=3)
|
||||||
|
0x00, 0x61, // Length of handshake message below (97 bytes)
|
||||||
|
|
||||||
|
// --- Handshake Protocol: ClientHello (97 bytes) ---
|
||||||
|
0x01, // Handshake Type: ClientHello (1)
|
||||||
|
0x00, 0x00, 0x5D, // Length of the rest of the message (93 bytes)
|
||||||
|
0x03, 0x03, // Client Version: TLS 1.2 (Major=3, Minor=3)
|
||||||
|
|
||||||
|
// Random (32 bytes)
|
||||||
|
0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00, 0x11,
|
||||||
|
0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
|
||||||
|
0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00, 0x11,
|
||||||
|
0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
|
||||||
|
|
||||||
|
// Session ID
|
||||||
|
0x00, // Session ID Length: 0 (new session)
|
||||||
|
|
||||||
|
// Cipher Suites (using modern GCM suites)
|
||||||
|
0x00, 0x04, // Cipher Suites Length: 4 bytes (2 suites)
|
||||||
|
0xC0, 0x2F, // Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
|
||||||
|
0xC0, 0x30, // Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
|
||||||
|
|
||||||
|
// Compression Methods
|
||||||
|
0x01, // Compression Methods Length: 1 byte
|
||||||
|
0x00, // Compression Method: NULL (0)
|
||||||
|
|
||||||
|
// --- Extensions (48 bytes) ---
|
||||||
|
0x00, 0x30, // Extensions Length: 48 bytes
|
||||||
|
// Extension: Server Name Indication (SNI) (20 bytes)
|
||||||
|
0x00, 0x00, 0x00, 0x10, 0x00, 0x0E, 0x00, 0x00, 0x0B,
|
||||||
|
'e', 'x', 'a', 'm', 'p', 'l', 'e', '.', 'c', 'o', 'm',
|
||||||
|
// Extension: Signature Algorithms (10 bytes) - CRITICAL for TLS 1.2
|
||||||
|
0x00, 0x0D, // Extension Type: signature_algorithms (13)
|
||||||
|
0x00, 0x06, // Extension Length: 6 bytes
|
||||||
|
0x00, 0x04, // Hash/Signature Algorithm List Length: 4 bytes
|
||||||
|
0x04, 0x01, // Algorithm: rsa_pkcs1_sha256
|
||||||
|
0x05, 0x01, // Algorithm: rsa_pkcs1_sha384
|
||||||
|
// Extension: Application-Layer Protocol Negotiation (ALPN) (18 bytes)
|
||||||
|
0x00, 0x10, // Extension Type: application_layer_protocol_negotiation (16)
|
||||||
|
0x00, 0x0E, // Extension Length: 14 bytes
|
||||||
|
0x00, 0x0C, // ALPN Extension Length: 12 bytes
|
||||||
|
// ALPN Protocol: "h2" (HTTP/2)
|
||||||
|
0x02, 'h', '2',
|
||||||
|
// ALPN Protocol: "http/1.1"
|
||||||
|
0x08, 'h', 't', 't', 'p', '/', '1', '.', '1',
|
||||||
|
}
|
||||||
|
|
||||||
|
// A valid TLS 1.3 Client Hello (captured from a real connection)
|
||||||
|
tls13ClientHello := []byte{
|
||||||
|
0x16, // Content Type: Handshake (22)
|
||||||
|
0x03, 0x01, // Version: TLS 1.0 (for compatibility in a 1.3 hello)
|
||||||
|
0x01, 0x3a, // Length
|
||||||
|
0x01, 0x00, 0x01, 0x36, 0x03, 0x03, 0xb1,
|
||||||
|
0x40, 0xd3, 0xf1, 0x7d, 0xa3, 0xb8, 0x33, 0xac, 0xad, 0x21, 0x79, 0x9c,
|
||||||
|
0xbe, 0x39, 0x96, 0x08, 0x49, 0x3b, 0x53, 0x75, 0xa0, 0x1b, 0xee, 0x6e,
|
||||||
|
0x6a, 0xbe, 0x6c, 0x41, 0xdf, 0x6c, 0xf4, 0x20, 0xa4, 0xaa, 0x0c, 0xca,
|
||||||
|
0xd4, 0x37, 0x76, 0x5f, 0x49, 0xc6, 0x06, 0x9b, 0xac, 0x90, 0x89, 0x76,
|
||||||
|
0x1c, 0xc7, 0xc4, 0x12, 0xb4, 0x4a, 0xe0, 0x27, 0x72, 0x89, 0x97, 0x85,
|
||||||
|
0x76, 0xf8, 0xc8, 0x83, 0x00, 0x62, 0x13, 0x03, 0x13, 0x02, 0x13, 0x01,
|
||||||
|
0xcc, 0xa9, 0xcc, 0xa8, 0xcc, 0xaa, 0xc0, 0x30, 0xc0, 0x2c, 0xc0, 0x28,
|
||||||
|
0xc0, 0x24, 0xc0, 0x14, 0xc0, 0x0a, 0x00, 0x9f, 0x00, 0x6b, 0x00, 0x39,
|
||||||
|
0xff, 0x85, 0x00, 0xc4, 0x00, 0x88, 0x00, 0x81, 0x00, 0x9d, 0x00, 0x3d,
|
||||||
|
0x00, 0x35, 0x00, 0xc0, 0x00, 0x84, 0xc0, 0x2f, 0xc0, 0x2b, 0xc0, 0x27,
|
||||||
|
0xc0, 0x23, 0xc0, 0x13, 0xc0, 0x09, 0x00, 0x9e, 0x00, 0x67, 0x00, 0x33,
|
||||||
|
0x00, 0xbe, 0x00, 0x45, 0x00, 0x9c, 0x00, 0x3c, 0x00, 0x2f, 0x00, 0xba,
|
||||||
|
0x00, 0x41, 0xc0, 0x11, 0xc0, 0x07, 0x00, 0x05, 0x00, 0x04, 0xc0, 0x12,
|
||||||
|
0xc0, 0x08, 0x00, 0x16, 0x00, 0x0a, 0x00, 0xff, 0x01, 0x00, 0x00, 0x8b,
|
||||||
|
0x00, 0x2b, 0x00, 0x09, 0x08, 0x03, 0x04, 0x03, 0x03, 0x03, 0x02, 0x03,
|
||||||
|
0x01, 0x00, 0x33, 0x00, 0x26, 0x00, 0x24, 0x00, 0x1d, 0x00, 0x20, 0x2c,
|
||||||
|
0x4b, 0xaa, 0xb4, 0xb3, 0xc8, 0x93, 0xcd, 0x5c, 0x24, 0xb9, 0x9b, 0xd4,
|
||||||
|
0x59, 0x04, 0xfe, 0x69, 0xaf, 0x68, 0xb9, 0xa6, 0x36, 0xbb, 0xab, 0x87,
|
||||||
|
0xfa, 0x15, 0x59, 0xea, 0xdd, 0x38, 0x68, 0x00, 0x00, 0x00, 0x0e, 0x00,
|
||||||
|
0x0c, 0x00, 0x00, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
|
||||||
|
0x74, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x0a, 0x00,
|
||||||
|
0x08, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x00, 0x0d, 0x00,
|
||||||
|
0x18, 0x00, 0x16, 0x08, 0x06, 0x06, 0x01, 0x06, 0x03, 0x08, 0x05, 0x05,
|
||||||
|
0x01, 0x05, 0x03, 0x08, 0x04, 0x04, 0x01, 0x04, 0x03, 0x02, 0x01, 0x02,
|
||||||
|
0x03, 0x00, 0x10, 0x00, 0x0e, 0x00, 0x0c, 0x02, 0x68, 0x32, 0x08, 0x68,
|
||||||
|
0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invalid data (Postgres client startup)
|
||||||
|
pgClientStartup := []byte{
|
||||||
|
0x00, 0x00, 0x00, 0x25, 0x00, 0x03, 0x00, 0x00,
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() { Strict = false }()
|
||||||
|
for _, strict := range []bool{false, true} {
|
||||||
|
Strict = strict
|
||||||
|
|
||||||
|
name := "loose"
|
||||||
|
if strict {
|
||||||
|
name = "strict"
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
|
||||||
|
t.Run("SSLv3 Client Hello", func(t *testing.T) {
|
||||||
|
p, err := Detect(Client, sslV3ClientHello)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t.Logf("detected %s version %s", p.Name, p.Version)
|
||||||
|
if p.Name != ProtocolSSL {
|
||||||
|
t.Fatalf("expected ssl protocol, got %s", p.Name)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("TLS 1.1 Client Hello", func(t *testing.T) {
|
||||||
|
p, err := Detect(Client, tls11ClientHello)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t.Logf("detected %s version %s", p.Name, p.Version)
|
||||||
|
if p.Name != ProtocolTLS {
|
||||||
|
t.Fatalf("expected tls protocol, got %s", p.Name)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("TLS 1.1 partial Client Hello", func(t *testing.T) {
|
||||||
|
p, err := Detect(Client, tls11ClientHelloPartial)
|
||||||
|
if strict {
|
||||||
|
if !errors.Is(err, ErrUnknown) {
|
||||||
|
t.Fatalf("expected unknown format, got error %T: %q", err, err)
|
||||||
|
} else {
|
||||||
|
t.Logf("error %q, as expected", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t.Logf("detected %s version %s", p.Name, p.Version)
|
||||||
|
if p.Name != ProtocolTLS {
|
||||||
|
t.Fatalf("expected tls protocol, got %s", p.Name)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("TLS 1.2 Client Hello", func(t *testing.T) {
|
||||||
|
p, err := Detect(Client, tls12ClientHello)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t.Logf("detected %s version %s", p.Name, p.Version)
|
||||||
|
if p.Name != ProtocolTLS {
|
||||||
|
t.Fatalf("expected tls protocol, got %s", p.Name)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("TLS 1.3 Client Hello", func(t *testing.T) {
|
||||||
|
p, err := Detect(Client, tls13ClientHello)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t.Logf("detected %s version %s", p.Name, p.Version)
|
||||||
|
if p.Name != ProtocolTLS {
|
||||||
|
t.Fatalf("expected tls protocol, got %s", p.Name)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Invalid PostgreSQL", func(t *testing.T) {
|
||||||
|
_, err := Detect(Server, pgClientStartup)
|
||||||
|
if !errors.Is(err, ErrUnknown) {
|
||||||
|
t.Fatalf("expected unknown format, got error %T: %q", err, err)
|
||||||
|
} else {
|
||||||
|
t.Logf("error %q, as expected", err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testDecodeHexString(s string) ([]byte, error) {
|
||||||
|
s = strings.TrimSpace(s)
|
||||||
|
s = strings.ReplaceAll(s, " ", "")
|
||||||
|
s = strings.ReplaceAll(s, "\n", "")
|
||||||
|
s = strings.ReplaceAll(s, "\t", "")
|
||||||
|
return hex.DecodeString(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testMustDecodeHexString(s string) []byte {
|
||||||
|
b, err := testDecodeHexString(s)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
128
protocol/intercept.go
Normal file
128
protocol/intercept.go
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
package protocol
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"sync/atomic"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Intercepted is the result returned by [Interceptor.Detect].
|
||||||
|
type Intercepted struct {
|
||||||
|
Direction Direction
|
||||||
|
Protocol *Protocol
|
||||||
|
Error error
|
||||||
|
}
|
||||||
|
|
||||||
|
// Interceptor intercepts reads from client or server.
|
||||||
|
type Interceptor struct {
|
||||||
|
clientBytes chan []byte
|
||||||
|
clientReader *readInterceptor
|
||||||
|
serverBytes chan []byte
|
||||||
|
serverReader *readInterceptor
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInterceptor creates a new (transparent) protocol interceptor.
|
||||||
|
func NewInterceptor() *Interceptor {
|
||||||
|
return &Interceptor{
|
||||||
|
clientBytes: make(chan []byte, 1),
|
||||||
|
serverBytes: make(chan []byte, 1),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type readInterceptor struct {
|
||||||
|
net.Conn
|
||||||
|
bytes chan []byte
|
||||||
|
once atomic.Bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func newReadInterceptor(c net.Conn, bytes chan []byte) *readInterceptor {
|
||||||
|
return &readInterceptor{
|
||||||
|
Conn: c,
|
||||||
|
bytes: bytes,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cancel any future Read interceptions and closes the channel.
|
||||||
|
func (r *readInterceptor) Cancel() {
|
||||||
|
if r == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
r.once.Store(true)
|
||||||
|
close(r.bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *readInterceptor) Read(p []byte) (n int, err error) {
|
||||||
|
if r.once.CompareAndSwap(false, true) {
|
||||||
|
if n, err = r.Conn.Read(p); n > 0 {
|
||||||
|
// We create a copy, since the Read caller may modify p
|
||||||
|
// immediately after reading.
|
||||||
|
data := make([]byte, n)
|
||||||
|
copy(data, p[:n])
|
||||||
|
// Buffer the bytes in the channel.
|
||||||
|
r.bytes <- data
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return r.Conn.Read(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Client binds the client connection to the interceptor.
|
||||||
|
func (i *Interceptor) Client(c net.Conn) net.Conn {
|
||||||
|
if ri, ok := c.(*readInterceptor); ok {
|
||||||
|
return ri
|
||||||
|
}
|
||||||
|
i.clientReader = newReadInterceptor(c, i.clientBytes)
|
||||||
|
return i.clientReader
|
||||||
|
}
|
||||||
|
|
||||||
|
// Server binds the server connection to the interceptor.
|
||||||
|
func (i *Interceptor) Server(c net.Conn) net.Conn {
|
||||||
|
if ri, ok := c.(*readInterceptor); ok {
|
||||||
|
return ri
|
||||||
|
}
|
||||||
|
i.serverReader = newReadInterceptor(c, i.serverBytes)
|
||||||
|
return i.serverReader
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detect runs protocol detection on the previously bound Client and Server connection.
|
||||||
|
//
|
||||||
|
// It waits until either the client or the server performs a read operation,
|
||||||
|
// which is then used for running protocol detection. If the read operation
|
||||||
|
// takes longer than timeout, an error is returned.
|
||||||
|
//
|
||||||
|
// The returned channel always yields one result and is then closed.
|
||||||
|
func (i *Interceptor) Detect(timeout time.Duration) <-chan *Intercepted {
|
||||||
|
var interceptc = make(chan *Intercepted, 1)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
// Make sure all channels are closed once we finish processing.
|
||||||
|
defer close(interceptc)
|
||||||
|
defer i.clientReader.Cancel()
|
||||||
|
defer i.serverReader.Cancel()
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-time.After(timeout): // timeout
|
||||||
|
interceptc <- &Intercepted{
|
||||||
|
Error: ErrTimeout,
|
||||||
|
}
|
||||||
|
|
||||||
|
case data := <-i.clientBytes: // client sent banner
|
||||||
|
p, err := Detect(Client, data)
|
||||||
|
interceptc <- &Intercepted{
|
||||||
|
Direction: Client,
|
||||||
|
Protocol: p,
|
||||||
|
Error: err,
|
||||||
|
}
|
||||||
|
|
||||||
|
case data := <-i.serverBytes: // server sent banner
|
||||||
|
p, err := Detect(Server, data)
|
||||||
|
interceptc <- &Intercepted{
|
||||||
|
Direction: Server,
|
||||||
|
Protocol: p,
|
||||||
|
Error: err,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
return interceptc
|
||||||
|
}
|
76
protocol/limit.go
Normal file
76
protocol/limit.go
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
package protocol
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
|
)
|
||||||
|
|
||||||
|
// AcceptFunc receives a direction and a detected protocol.
|
||||||
|
type AcceptFunc func(Direction, *Protocol) error
|
||||||
|
|
||||||
|
// Limit the connection protocol, by running a detection after either side sends
|
||||||
|
// a banner within timeout.
|
||||||
|
//
|
||||||
|
// If no protocol could be detected, the accept function is called with a nil
|
||||||
|
// argument to check if we should proceed.
|
||||||
|
//
|
||||||
|
// If the accept function returns false, the connection will be closed.
|
||||||
|
func Limit(conn net.Conn, accept AcceptFunc) net.Conn {
|
||||||
|
if accept == nil {
|
||||||
|
// Nothing to do here.
|
||||||
|
return conn
|
||||||
|
}
|
||||||
|
|
||||||
|
return &connLimiter{
|
||||||
|
Conn: conn,
|
||||||
|
accept: accept,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type connLimiter struct {
|
||||||
|
net.Conn
|
||||||
|
accept AcceptFunc
|
||||||
|
acceptOnce sync.Once
|
||||||
|
acceptError atomic.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *connLimiter) init(readData, writeData []byte) {
|
||||||
|
l.acceptOnce.Do(func() {
|
||||||
|
var (
|
||||||
|
dir Direction
|
||||||
|
data []byte
|
||||||
|
)
|
||||||
|
if readData != nil {
|
||||||
|
// init called by initial read
|
||||||
|
dir, data = Server, readData
|
||||||
|
} else {
|
||||||
|
// init called by initial write
|
||||||
|
dir, data = Client, writeData
|
||||||
|
}
|
||||||
|
protocol, _ := Detect(dir, data)
|
||||||
|
if err := l.accept(dir, protocol); err != nil {
|
||||||
|
l.acceptError.Store(err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *connLimiter) Read(p []byte) (n int, err error) {
|
||||||
|
var ok bool
|
||||||
|
if err, ok = l.acceptError.Load().(error); ok && err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if n, err = l.Conn.Read(p); n > 0 {
|
||||||
|
l.init(p[:n], nil)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *connLimiter) Write(p []byte) (n int, err error) {
|
||||||
|
l.init(nil, p)
|
||||||
|
var ok bool
|
||||||
|
if err, ok = l.acceptError.Load().(error); ok && err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return l.Conn.Write(p)
|
||||||
|
}
|
47
protocol/protocol.go
Normal file
47
protocol/protocol.go
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
package protocol
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Protocols supported by this package.
|
||||||
|
const (
|
||||||
|
ProtocolDNS = "dns"
|
||||||
|
ProtocolHTTP = "http"
|
||||||
|
ProtocolMySQL = "mysql"
|
||||||
|
ProtocolPostgreSQL = "postgresql"
|
||||||
|
ProtocolSSH = "ssh"
|
||||||
|
ProtocolSSL = "ssl"
|
||||||
|
ProtocolTLS = "tls"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Protocol struct {
|
||||||
|
Name string
|
||||||
|
Version Version
|
||||||
|
}
|
||||||
|
|
||||||
|
type Version struct {
|
||||||
|
Major int
|
||||||
|
Minor int
|
||||||
|
Patch int
|
||||||
|
Extra string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v Version) String() string {
|
||||||
|
p := make([]string, 0, 3)
|
||||||
|
if v.Major >= 0 {
|
||||||
|
p = append(p, strconv.Itoa(v.Major))
|
||||||
|
if v.Minor >= 0 {
|
||||||
|
p = append(p, strconv.Itoa(v.Minor))
|
||||||
|
if v.Patch >= 0 {
|
||||||
|
p = append(p, strconv.Itoa(v.Patch))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s := strings.Join(p, ".")
|
||||||
|
if v.Extra != "" {
|
||||||
|
return s + "-" + v.Extra
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
BIN
testdata/tls13-clienthello.bin
vendored
Normal file
BIN
testdata/tls13-clienthello.bin
vendored
Normal file
Binary file not shown.
455
tls.go
Normal file
455
tls.go
Normal file
@@ -0,0 +1,455 @@
|
|||||||
|
package dpi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/cryptobyte"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TLSExtension is a TLS extension.
|
||||||
|
type TLSExtension struct {
|
||||||
|
Type uint16
|
||||||
|
Data []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// TLSRecord is a TLS record.
|
||||||
|
type TLSRecord struct {
|
||||||
|
Raw []byte
|
||||||
|
Type uint8
|
||||||
|
Version uint16
|
||||||
|
Length uint16
|
||||||
|
Data []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func DecodeTLSRecord(data []byte) (*TLSRecord, error) {
|
||||||
|
var (
|
||||||
|
stream = cryptobyte.String(data)
|
||||||
|
record = &TLSRecord{Raw: data}
|
||||||
|
)
|
||||||
|
|
||||||
|
if !stream.ReadUint8(&record.Type) ||
|
||||||
|
!stream.ReadUint16(&record.Version) ||
|
||||||
|
!stream.ReadUint16(&record.Length) {
|
||||||
|
return nil, DecodeError{
|
||||||
|
Reason: "invalid TLS record header",
|
||||||
|
Err: io.ErrUnexpectedEOF,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !stream.ReadBytes(&record.Data, int(record.Length)) {
|
||||||
|
return nil, DecodeError{
|
||||||
|
Reason: "invalid TLS record data",
|
||||||
|
Err: io.ErrUnexpectedEOF,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !stream.Empty() {
|
||||||
|
return nil, DecodeError{
|
||||||
|
Reason: "extraneous data after TLS record",
|
||||||
|
Err: ErrInvalid,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return record, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// TLSClientHello is a TLS ClientHello packet as part of the TLS handshake.
|
||||||
|
type TLSClientHello struct {
|
||||||
|
Raw []byte
|
||||||
|
Version TLSVersion
|
||||||
|
Random []byte
|
||||||
|
SessionID []byte
|
||||||
|
CipherSuites []uint16
|
||||||
|
CompressionMethods []uint8
|
||||||
|
Extensions []TLSExtension
|
||||||
|
ServerName string
|
||||||
|
SupportedCurves []uint16 // aka "Supported Groups"
|
||||||
|
SupportedSignatureAlgorithms []TLSSignatureScheme // RFC 5246, Section 7.4.1.4.1
|
||||||
|
ALPNProtocols []string // RFC 7301, Section 3.1
|
||||||
|
SupportedVersions []TLSVersion // RFC 8446, Section 4.2.1z
|
||||||
|
}
|
||||||
|
|
||||||
|
func DecodeTLSClientHello(data []byte) (*TLSClientHello, error) {
|
||||||
|
var (
|
||||||
|
stream = cryptobyte.String(data)
|
||||||
|
hello = &TLSClientHello{Raw: data}
|
||||||
|
)
|
||||||
|
|
||||||
|
// Read header (4 bytes)
|
||||||
|
var handshakeType uint8
|
||||||
|
if !stream.ReadUint8(&handshakeType) || handshakeType != tlsTypeClientHello {
|
||||||
|
return nil, DecodeError{
|
||||||
|
Reason: fmt.Sprintf("expected a TLS ClientHello (0x%02X), got 0x%02X", tlsTypeClientHello, handshakeType),
|
||||||
|
Err: ErrInvalid,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var record cryptobyte.String
|
||||||
|
if !stream.ReadUint24LengthPrefixed(&record) {
|
||||||
|
return nil, DecodeError{
|
||||||
|
Reason: "incomplete TLS record",
|
||||||
|
Err: io.ErrUnexpectedEOF,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !stream.Empty() {
|
||||||
|
return nil, DecodeError{
|
||||||
|
Reason: "invalid TLS record length",
|
||||||
|
Err: ErrInvalid,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parser client version.
|
||||||
|
var version uint16
|
||||||
|
if !record.ReadUint16(&version) {
|
||||||
|
return nil, DecodeError{
|
||||||
|
Reason: "incomplete TLS version",
|
||||||
|
Err: io.ErrUnexpectedEOF,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hello.Version = TLSVersion(version)
|
||||||
|
|
||||||
|
// Parse random (32 bytes)
|
||||||
|
if !record.ReadBytes(&hello.Random, 32) {
|
||||||
|
return nil, DecodeError{
|
||||||
|
Reason: "incomplete TLS random bytes",
|
||||||
|
Err: io.ErrUnexpectedEOF,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse session ID
|
||||||
|
var sessionID cryptobyte.String
|
||||||
|
if !record.ReadUint8LengthPrefixed(&sessionID) {
|
||||||
|
return nil, DecodeError{
|
||||||
|
Reason: "incomplete TLS session ID",
|
||||||
|
Err: io.ErrUnexpectedEOF,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hello.SessionID = sessionID
|
||||||
|
|
||||||
|
// Parse cipher suites
|
||||||
|
var cipherSuites cryptobyte.String
|
||||||
|
if !record.ReadUint16LengthPrefixed(&cipherSuites) {
|
||||||
|
return nil, DecodeError{
|
||||||
|
Reason: "incomplete TLS cipher suites bytes",
|
||||||
|
Err: io.ErrUnexpectedEOF,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for !cipherSuites.Empty() {
|
||||||
|
var cipherSuite uint16
|
||||||
|
if !cipherSuites.ReadUint16(&cipherSuite) {
|
||||||
|
return nil, DecodeError{
|
||||||
|
Reason: "incomplete TLS cipher suite",
|
||||||
|
Err: io.ErrUnexpectedEOF,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hello.CipherSuites = append(hello.CipherSuites, cipherSuite)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse compression methods
|
||||||
|
var compressionMethods cryptobyte.String
|
||||||
|
if !record.ReadUint8LengthPrefixed(&compressionMethods) {
|
||||||
|
return nil, DecodeError{
|
||||||
|
Reason: "incomplete TLS compression methods bytes",
|
||||||
|
Err: io.ErrUnexpectedEOF,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hello.CompressionMethods = compressionMethods
|
||||||
|
|
||||||
|
// Parse extensions (optional)
|
||||||
|
if record.Empty() {
|
||||||
|
return hello, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var extensions cryptobyte.String
|
||||||
|
if !record.ReadUint16LengthPrefixed(&extensions) {
|
||||||
|
return nil, DecodeError{
|
||||||
|
Reason: "incomplete TLS extensions",
|
||||||
|
Err: io.ErrUnexpectedEOF,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !record.Empty() {
|
||||||
|
return nil, DecodeError{
|
||||||
|
Reason: "extraneous TLS extension data",
|
||||||
|
Err: io.ErrUnexpectedEOF,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for !extensions.Empty() {
|
||||||
|
var (
|
||||||
|
extension TLSExtension
|
||||||
|
extensionData = cryptobyte.String(extension.Data)
|
||||||
|
)
|
||||||
|
if !extensions.ReadUint16(&extension.Type) || !extensions.ReadUint16LengthPrefixed(&extensionData) {
|
||||||
|
return nil, DecodeError{
|
||||||
|
Reason: "incomplete TLS extension record data",
|
||||||
|
Err: io.ErrUnexpectedEOF,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hello.Extensions = append(hello.Extensions, extension)
|
||||||
|
|
||||||
|
switch extension.Type {
|
||||||
|
case tlsExtensionServerName:
|
||||||
|
// RFC 6066, Section 3
|
||||||
|
if !readTLSServerName(extensionData, &hello.ServerName) {
|
||||||
|
return nil, DecodeError{
|
||||||
|
Reason: "invalid TLS server name extension data",
|
||||||
|
Err: io.ErrUnexpectedEOF,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case tlsExtensionSupportedGroups:
|
||||||
|
// RFC 4492, Section 5.1.1
|
||||||
|
// RFC 8446, Section 4.2.7
|
||||||
|
if !readTLSSupportedGroups(extensionData, &hello.SupportedCurves) {
|
||||||
|
return nil, DecodeError{
|
||||||
|
Reason: "invalid TLS supported groups extension data",
|
||||||
|
Err: io.ErrUnexpectedEOF,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case tlsExtensionSignatureAlgorithms:
|
||||||
|
// RFC 5246, Section 7.4.1
|
||||||
|
if !readTLSSignatureAlgorithms(extensionData, &hello.SupportedSignatureAlgorithms) {
|
||||||
|
return nil, DecodeError{
|
||||||
|
Reason: "invalid TLS supported signature algorithms extension data",
|
||||||
|
Err: io.ErrUnexpectedEOF,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case tlsExtensionALPN:
|
||||||
|
if !readTLSALPN(extensionData, &hello.ALPNProtocols) {
|
||||||
|
return nil, DecodeError{
|
||||||
|
Reason: "invalid TLS ALPN extension data",
|
||||||
|
Err: io.ErrUnexpectedEOF,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case tlsExtensionSupportedVersions:
|
||||||
|
if !readTLSSupportedVersions(extensionData, &hello.SupportedVersions) {
|
||||||
|
return nil, DecodeError{
|
||||||
|
Reason: "invalid TLS supported versions extension data",
|
||||||
|
Err: io.ErrUnexpectedEOF,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return hello, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func DecodeTLSClientHelloHandshake(data []byte) (*TLSClientHello, error) {
|
||||||
|
record, err := DecodeTLSRecord(data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if record.Type != tlsRecordTypeHandshake {
|
||||||
|
return nil, DecodeError{
|
||||||
|
Reason: fmt.Sprintf("expected TLS handshake record type (0x%02X), got 0x%02X", tlsRecordTypeHandshake, record.Type),
|
||||||
|
Err: ErrInvalid,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return DecodeTLSClientHello(record.Data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TLSServerHello is a TLS ServerHello packet as part of the TLS handshake.
|
||||||
|
type TLSServerHello struct {
|
||||||
|
Raw []byte
|
||||||
|
Version TLSVersion
|
||||||
|
RandomTimestamp time.Time
|
||||||
|
Random []byte
|
||||||
|
SessionID []byte
|
||||||
|
CipherSuite uint16
|
||||||
|
CompressionMethod uint8
|
||||||
|
Extensions []TLSExtension
|
||||||
|
}
|
||||||
|
|
||||||
|
func DecodeTLSServerHello(data []byte) (*TLSServerHello, error) {
|
||||||
|
var (
|
||||||
|
stream = cryptobyte.String(data)
|
||||||
|
hello = &TLSServerHello{Raw: data}
|
||||||
|
)
|
||||||
|
|
||||||
|
// Read header (4 bytes)
|
||||||
|
var handshakeType uint8
|
||||||
|
if !stream.ReadUint8(&handshakeType) || handshakeType != tlsTypeServerHello {
|
||||||
|
return nil, DecodeError{
|
||||||
|
Reason: fmt.Sprintf("expected a TLS ServerHello (0x%02X), got 0x%02X", tlsTypeServerHello, handshakeType),
|
||||||
|
Err: ErrInvalid,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var record cryptobyte.String
|
||||||
|
if !stream.ReadUint24LengthPrefixed(&record) {
|
||||||
|
return nil, DecodeError{
|
||||||
|
Reason: "incomplete TLS record",
|
||||||
|
Err: io.ErrUnexpectedEOF,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !stream.Empty() {
|
||||||
|
return nil, DecodeError{
|
||||||
|
Reason: "invalid TLS record length",
|
||||||
|
Err: ErrInvalid,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parser server version.
|
||||||
|
var version uint16
|
||||||
|
if !record.ReadUint16(&version) {
|
||||||
|
return nil, DecodeError{
|
||||||
|
Reason: "incomplete TLS version",
|
||||||
|
Err: io.ErrUnexpectedEOF,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hello.Version = TLSVersion(version)
|
||||||
|
|
||||||
|
// Parse random (32 bytes)
|
||||||
|
if !record.ReadBytes(&hello.Random, 32) {
|
||||||
|
return nil, DecodeError{
|
||||||
|
Reason: "incomplete TLS random bytes",
|
||||||
|
Err: io.ErrUnexpectedEOF,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hello.RandomTimestamp = time.Unix(int64(binary.BigEndian.Uint32(hello.Random)), 0)
|
||||||
|
|
||||||
|
// Parse session ID
|
||||||
|
var sessionID cryptobyte.String
|
||||||
|
if !record.ReadUint8LengthPrefixed(&sessionID) {
|
||||||
|
return nil, DecodeError{
|
||||||
|
Reason: "incomplete TLS session ID",
|
||||||
|
Err: io.ErrUnexpectedEOF,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hello.SessionID = sessionID
|
||||||
|
|
||||||
|
// Parse cipher suite
|
||||||
|
if !record.ReadUint16(&hello.CipherSuite) {
|
||||||
|
return nil, DecodeError{
|
||||||
|
Reason: "incomplete TLS cipher suite",
|
||||||
|
Err: io.ErrUnexpectedEOF,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse compression method
|
||||||
|
if !record.ReadUint8(&hello.CompressionMethod) {
|
||||||
|
return nil, DecodeError{
|
||||||
|
Reason: "incomplete TLS compression method",
|
||||||
|
Err: io.ErrUnexpectedEOF,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse extensions (optional)
|
||||||
|
if record.Empty() {
|
||||||
|
return hello, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var extensions cryptobyte.String
|
||||||
|
if !record.ReadUint16LengthPrefixed(&extensions) {
|
||||||
|
return nil, DecodeError{
|
||||||
|
Reason: "incomplete TLS extensions",
|
||||||
|
Err: io.ErrUnexpectedEOF,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !record.Empty() {
|
||||||
|
return nil, DecodeError{
|
||||||
|
Reason: "extraneous TLS extension data",
|
||||||
|
Err: io.ErrUnexpectedEOF,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for !extensions.Empty() {
|
||||||
|
var (
|
||||||
|
extension TLSExtension
|
||||||
|
extensionData = cryptobyte.String(extension.Data)
|
||||||
|
)
|
||||||
|
if !extensions.ReadUint16(&extension.Type) || !extensions.ReadUint16LengthPrefixed(&extensionData) {
|
||||||
|
return nil, DecodeError{
|
||||||
|
Reason: "incomplete TLS extension record data",
|
||||||
|
Err: io.ErrUnexpectedEOF,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hello.Extensions = append(hello.Extensions, extension)
|
||||||
|
}
|
||||||
|
|
||||||
|
return hello, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func readTLSServerName(data cryptobyte.String, serverName *string) bool {
|
||||||
|
var list cryptobyte.String
|
||||||
|
if !data.ReadUint16LengthPrefixed(&list) || list.Empty() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for !list.Empty() {
|
||||||
|
var (
|
||||||
|
nameType uint8
|
||||||
|
name cryptobyte.String
|
||||||
|
)
|
||||||
|
if !list.ReadUint8(&nameType) || !list.ReadUint16LengthPrefixed(&name) || name.Empty() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if nameType != 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if *serverName == "" {
|
||||||
|
*serverName = string(name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func readTLSSupportedGroups(data cryptobyte.String, supported *[]uint16) bool {
|
||||||
|
var groups cryptobyte.String
|
||||||
|
if !data.ReadUint16LengthPrefixed(&groups) || groups.Empty() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for !groups.Empty() {
|
||||||
|
var group uint16
|
||||||
|
if !groups.ReadUint16(&group) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
*supported = append(*supported, group)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func readTLSSignatureAlgorithms(data cryptobyte.String, supported *[]TLSSignatureScheme) bool {
|
||||||
|
var algorithms cryptobyte.String
|
||||||
|
if !data.ReadUint16LengthPrefixed(&algorithms) || algorithms.Empty() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for !algorithms.Empty() {
|
||||||
|
var algorithm uint16
|
||||||
|
if !algorithms.ReadUint16(&algorithm) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
*supported = append(*supported, TLSSignatureScheme(algorithm))
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func readTLSALPN(data cryptobyte.String, alpnProtocols *[]string) bool {
|
||||||
|
var list cryptobyte.String
|
||||||
|
if !data.ReadUint16LengthPrefixed(&list) || list.Empty() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for !list.Empty() {
|
||||||
|
var proto cryptobyte.String
|
||||||
|
if !list.ReadUint8LengthPrefixed(&proto) || proto.Empty() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
*alpnProtocols = append(*alpnProtocols, string(proto))
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func readTLSSupportedVersions(data cryptobyte.String, versions *[]TLSVersion) bool {
|
||||||
|
var list cryptobyte.String
|
||||||
|
if !data.ReadUint8LengthPrefixed(&list) || list.Empty() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for !list.Empty() {
|
||||||
|
var version uint16
|
||||||
|
if !list.ReadUint16(&version) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
*versions = append(*versions, TLSVersion(version))
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
525
tls_const.go
Normal file
525
tls_const.go
Normal file
@@ -0,0 +1,525 @@
|
|||||||
|
package dpi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/tls"
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:generate stringer -linecomment -type=TLSCipherSuite,TLSSignatureScheme -output=tls_const_string.go
|
||||||
|
|
||||||
|
// TLS Version
|
||||||
|
type TLSVersion uint16
|
||||||
|
|
||||||
|
func (version TLSVersion) String() string {
|
||||||
|
return TLSVersionName(version)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TLS versions.
|
||||||
|
const (
|
||||||
|
VersionSSL30 TLSVersion = 0x0300 // SSLv3
|
||||||
|
VersionTLS10 TLSVersion = tls.VersionTLS10 // TLS 1.0
|
||||||
|
VersionTLS11 TLSVersion = tls.VersionTLS11 // TLS 1.1
|
||||||
|
VersionTLS12 TLSVersion = tls.VersionTLS12 // TLS 1.2
|
||||||
|
VersionTLS13 TLSVersion = tls.VersionTLS13 // TLS 1.3
|
||||||
|
VersionTLS13Draft TLSVersion = 0x7F00 // TLS 1.3 (draft)
|
||||||
|
VersionTLS13Draft18 TLSVersion = 0x7F12 // TLS 1.3 (draft 18)
|
||||||
|
VersionTLS13Draft19 TLSVersion = 0x7F13 // TLS 1.3 (draft 19)
|
||||||
|
VersionTLS13Draft20 TLSVersion = 0x7F14 // TLS 1.3 (draft 20)
|
||||||
|
VersionTLS13Draft21 TLSVersion = 0x7F15 // TLS 1.3 (draft 21)
|
||||||
|
VersionTLS13Draft22 TLSVersion = 0x7F16 // TLS 1.3 (draft 22)
|
||||||
|
VersionTLS13Draft23 TLSVersion = 0x7F17 // TLS 1.3 (draft 23)
|
||||||
|
)
|
||||||
|
|
||||||
|
var tlsVersionName = map[TLSVersion]string{
|
||||||
|
VersionSSL30: "SSLv3",
|
||||||
|
VersionTLS10: "TLS 1.0",
|
||||||
|
VersionTLS11: "TLS 1.1",
|
||||||
|
VersionTLS12: "TLS 1.2",
|
||||||
|
VersionTLS13: "TLS 1.3",
|
||||||
|
VersionTLS13Draft: "TLS 1.3 (draft)",
|
||||||
|
VersionTLS13Draft18: "TLS 1.3 (draft 18)",
|
||||||
|
VersionTLS13Draft19: "TLS 1.3 (draft 19)",
|
||||||
|
VersionTLS13Draft20: "TLS 1.3 (draft 20)",
|
||||||
|
VersionTLS13Draft21: "TLS 1.3 (draft 21)",
|
||||||
|
VersionTLS13Draft22: "TLS 1.3 (draft 22)",
|
||||||
|
VersionTLS13Draft23: "TLS 1.3 (draft 23)",
|
||||||
|
}
|
||||||
|
|
||||||
|
func TLSVersionName(version TLSVersion) string {
|
||||||
|
if s, ok := tlsVersionName[version]; ok {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
return "TLSVersion(0x" + strconv.FormatUint(uint64(version), 16) + ")"
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
tlsRecordTypeChangeCipherSpec uint8 = 20
|
||||||
|
tlsRecordTypeAlert uint8 = 21
|
||||||
|
tlsRecordTypeHandshake uint8 = 22
|
||||||
|
tlsRecordTypeApplicationData uint8 = 23
|
||||||
|
)
|
||||||
|
|
||||||
|
// TLS handshake message types.
|
||||||
|
const (
|
||||||
|
tlsTypeHelloRequest uint8 = 0
|
||||||
|
tlsTypeClientHello uint8 = 1
|
||||||
|
tlsTypeServerHello uint8 = 2
|
||||||
|
tlsTypeNewSessionTicket uint8 = 4
|
||||||
|
tlsTypeEndOfEarlyData uint8 = 5
|
||||||
|
tlsTypeEncryptedExtensions uint8 = 8
|
||||||
|
tlsTypeCertificate uint8 = 11
|
||||||
|
tlsTypeServerKeyExchange uint8 = 12
|
||||||
|
tlsTypeCertificateRequest uint8 = 13
|
||||||
|
tlsTypeServerHelloDone uint8 = 14
|
||||||
|
tlsTypeCertificateVerify uint8 = 15
|
||||||
|
tlsTypeClientKeyExchange uint8 = 16
|
||||||
|
tlsTypeFinished uint8 = 20
|
||||||
|
tlsTypeCertificateStatus uint8 = 22
|
||||||
|
tlsTypeKeyUpdate uint8 = 24
|
||||||
|
tlsTypeMessageHash uint8 = 254
|
||||||
|
)
|
||||||
|
|
||||||
|
// TLS extensions.
|
||||||
|
const (
|
||||||
|
tlsExtensionServerName uint16 = 0
|
||||||
|
tlsExtensionStatusRequest uint16 = 5
|
||||||
|
tlsExtensionSupportedGroups uint16 = 10
|
||||||
|
tlsExtensionSupportedPoints uint16 = 11
|
||||||
|
tlsExtensionSignatureAlgorithms uint16 = 13
|
||||||
|
tlsExtensionALPN uint16 = 16
|
||||||
|
tlsExtensionStatusRequestV2 uint16 = 17
|
||||||
|
tlsExtensionSCT uint16 = 18
|
||||||
|
tlsExtensionExtendedMasterSecret uint16 = 23
|
||||||
|
tlsExtensionDelegatedCredentials uint16 = 34
|
||||||
|
tlsExtensionSessionTicket uint16 = 35
|
||||||
|
tlsExtensionPreSharedKey uint16 = 41
|
||||||
|
tlsExtensionEarlyData uint16 = 42
|
||||||
|
tlsExtensionSupportedVersions uint16 = 43
|
||||||
|
tlsExtensionCookie uint16 = 44
|
||||||
|
tlsExtensionPSKModes uint16 = 45
|
||||||
|
tlsExtensionCertificateAuthorities uint16 = 47
|
||||||
|
tlsExtensionSignatureAlgorithmsCert uint16 = 50
|
||||||
|
tlsExtensionKeyShare uint16 = 51
|
||||||
|
tlsExtensionQUICTransportParameters uint16 = 57
|
||||||
|
tlsExtensionRenegotiationInfo uint16 = 0xff01
|
||||||
|
tlsExtensionECHOuterExtensions uint16 = 0xfd00
|
||||||
|
tlsExtensionEncryptedClientHello uint16 = 0xfe0d
|
||||||
|
)
|
||||||
|
|
||||||
|
// TLS cipher suite.
|
||||||
|
type TLSCipherSuite uint16
|
||||||
|
|
||||||
|
// TLS cipher suites.
|
||||||
|
//
|
||||||
|
// See https://www.iana.org/assignments/tls-parameters/tls-parameters.xml
|
||||||
|
const (
|
||||||
|
TLS_NULL_WITH_NULL_NULL TLSCipherSuite = 0x0000
|
||||||
|
TLS_RSA_WITH_NULL_MD5 TLSCipherSuite = 0x0001 // RFC5246
|
||||||
|
TLS_RSA_WITH_NULL_SHA TLSCipherSuite = 0x0002 // RFC5246
|
||||||
|
TLS_RSA_EXPORT_WITH_RC4_40_MD5 TLSCipherSuite = 0x0003 // RFC4346 RFC6347
|
||||||
|
TLS_RSA_WITH_RC4_128_MD5 TLSCipherSuite = 0x0004 // RFC5246 RFC6347
|
||||||
|
TLS_RSA_WITH_RC4_128_SHA TLSCipherSuite = 0x0005 // RFC5246 RFC6347
|
||||||
|
TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 TLSCipherSuite = 0x0006 // RFC4346
|
||||||
|
TLS_RSA_WITH_IDEA_CBC_SHA TLSCipherSuite = 0x0007 // RFC8996
|
||||||
|
TLS_RSA_EXPORT_WITH_DES40_CBC_SHA TLSCipherSuite = 0x0008 // RFC4346
|
||||||
|
TLS_RSA_WITH_DES_CBC_SHA TLSCipherSuite = 0x0009 // RFC8996
|
||||||
|
TLS_RSA_WITH_3DES_EDE_CBC_SHA TLSCipherSuite = 0x000A // RFC5246
|
||||||
|
TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA TLSCipherSuite = 0x000B // RFC4346
|
||||||
|
TLS_DH_DSS_WITH_DES_CBC_SHA TLSCipherSuite = 0x000C // RFC8996
|
||||||
|
TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA TLSCipherSuite = 0x000D // RFC5246
|
||||||
|
TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA TLSCipherSuite = 0x000E // RFC4346
|
||||||
|
TLS_DH_RSA_WITH_DES_CBC_SHA TLSCipherSuite = 0x000F // RFC8996
|
||||||
|
TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA TLSCipherSuite = 0x0010 // RFC5246
|
||||||
|
TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA TLSCipherSuite = 0x0011 // RFC4346
|
||||||
|
TLS_DHE_DSS_WITH_DES_CBC_SHA TLSCipherSuite = 0x0012 // RFC8996
|
||||||
|
TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA TLSCipherSuite = 0x0013 // RFC5246
|
||||||
|
TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA TLSCipherSuite = 0x0014 // RFC4346
|
||||||
|
TLS_DHE_RSA_WITH_DES_CBC_SHA TLSCipherSuite = 0x0015 // RFC8996
|
||||||
|
TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA TLSCipherSuite = 0x0016 // RFC5246
|
||||||
|
TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 TLSCipherSuite = 0x0017 // RFC4346 RFC6347
|
||||||
|
TLS_DH_anon_WITH_RC4_128_MD5 TLSCipherSuite = 0x0018 // RFC5246 RFC6347
|
||||||
|
TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA TLSCipherSuite = 0x0019 // RFC4346
|
||||||
|
TLS_DH_anon_WITH_DES_CBC_SHA TLSCipherSuite = 0x001A // RFC8996
|
||||||
|
TLS_DH_anon_WITH_3DES_EDE_CBC_SHA TLSCipherSuite = 0x001B // RFC5246
|
||||||
|
TLS_KRB5_WITH_DES_CBC_SHA TLSCipherSuite = 0x001E // RFC2712 RFC-ietf-tls-rfc8447bis-14
|
||||||
|
TLS_KRB5_WITH_3DES_EDE_CBC_SHA TLSCipherSuite = 0x001F // RFC2712
|
||||||
|
TLS_KRB5_WITH_RC4_128_SHA TLSCipherSuite = 0x0020 // RFC2712 RFC6347 RFC-ietf-tls-rfc8447bis-14
|
||||||
|
TLS_KRB5_WITH_IDEA_CBC_SHA TLSCipherSuite = 0x0021 // RFC2712 RFC-ietf-tls-rfc8447bis-14
|
||||||
|
TLS_KRB5_WITH_DES_CBC_MD5 TLSCipherSuite = 0x0022 // RFC2712 RFC-ietf-tls-rfc8447bis-14
|
||||||
|
TLS_KRB5_WITH_3DES_EDE_CBC_MD5 TLSCipherSuite = 0x0023 // RFC2712
|
||||||
|
TLS_KRB5_WITH_RC4_128_MD5 TLSCipherSuite = 0x0024 // RFC2712 RFC6347 RFC-ietf-tls-rfc8447bis-14
|
||||||
|
TLS_KRB5_WITH_IDEA_CBC_MD5 TLSCipherSuite = 0x0025 // RFC2712 RFC-ietf-tls-rfc8447bis-14
|
||||||
|
TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA TLSCipherSuite = 0x0026 // RFC2712 RFC-ietf-tls-rfc8447bis-14
|
||||||
|
TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA TLSCipherSuite = 0x0027 // RFC2712 RFC-ietf-tls-rfc8447bis-14
|
||||||
|
TLS_KRB5_EXPORT_WITH_RC4_40_SHA TLSCipherSuite = 0x0028 // RFC2712 RFC6347 RFC-ietf-tls-rfc8447bis-14
|
||||||
|
TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5 TLSCipherSuite = 0x0029 // RFC2712 RFC-ietf-tls-rfc8447bis-14
|
||||||
|
TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5 TLSCipherSuite = 0x002A // RFC2712 RFC-ietf-tls-rfc8447bis-14
|
||||||
|
TLS_KRB5_EXPORT_WITH_RC4_40_MD5 TLSCipherSuite = 0x002B // RFC2712 RFC6347 RFC-ietf-tls-rfc8447bis-14
|
||||||
|
TLS_PSK_WITH_NULL_SHA TLSCipherSuite = 0x002C // RFC4785 RFC-ietf-tls-rfc8447bis-14
|
||||||
|
TLS_DHE_PSK_WITH_NULL_SHA TLSCipherSuite = 0x002D // RFC4785
|
||||||
|
TLS_RSA_PSK_WITH_NULL_SHA TLSCipherSuite = 0x002E // RFC4785
|
||||||
|
TLS_RSA_WITH_AES_128_CBC_SHA TLSCipherSuite = 0x002F // RFC5246
|
||||||
|
TLS_DH_DSS_WITH_AES_128_CBC_SHA TLSCipherSuite = 0x0030 // RFC5246
|
||||||
|
TLS_DH_RSA_WITH_AES_128_CBC_SHA TLSCipherSuite = 0x0031 // RFC5246
|
||||||
|
TLS_DHE_DSS_WITH_AES_128_CBC_SHA TLSCipherSuite = 0x0032 // RFC5246
|
||||||
|
TLS_DHE_RSA_WITH_AES_128_CBC_SHA TLSCipherSuite = 0x0033 // RFC5246
|
||||||
|
TLS_DH_anon_WITH_AES_128_CBC_SHA TLSCipherSuite = 0x0034 // RFC5246
|
||||||
|
TLS_RSA_WITH_AES_256_CBC_SHA TLSCipherSuite = 0x0035 // RFC5246
|
||||||
|
TLS_DH_DSS_WITH_AES_256_CBC_SHA TLSCipherSuite = 0x0036 // RFC5246
|
||||||
|
TLS_DH_RSA_WITH_AES_256_CBC_SHA TLSCipherSuite = 0x0037 // RFC5246
|
||||||
|
TLS_DHE_DSS_WITH_AES_256_CBC_SHA TLSCipherSuite = 0x0038 // RFC5246
|
||||||
|
TLS_DHE_RSA_WITH_AES_256_CBC_SHA TLSCipherSuite = 0x0039 // RFC5246
|
||||||
|
TLS_DH_anon_WITH_AES_256_CBC_SHA TLSCipherSuite = 0x003A // RFC5246
|
||||||
|
TLS_RSA_WITH_NULL_SHA256 TLSCipherSuite = 0x003B // RFC5246
|
||||||
|
TLS_RSA_WITH_AES_128_CBC_SHA256 TLSCipherSuite = 0x003C // RFC5246
|
||||||
|
TLS_RSA_WITH_AES_256_CBC_SHA256 TLSCipherSuite = 0x003D // RFC5246
|
||||||
|
TLS_DH_DSS_WITH_AES_128_CBC_SHA256 TLSCipherSuite = 0x003E // RFC5246
|
||||||
|
TLS_DH_RSA_WITH_AES_128_CBC_SHA256 TLSCipherSuite = 0x003F // RFC5246
|
||||||
|
TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 TLSCipherSuite = 0x0040 // RFC5246
|
||||||
|
TLS_RSA_WITH_CAMELLIA_128_CBC_SHA TLSCipherSuite = 0x0041 // RFC5932
|
||||||
|
TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA TLSCipherSuite = 0x0042 // RFC5932
|
||||||
|
TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA TLSCipherSuite = 0x0043 // RFC5932
|
||||||
|
TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA TLSCipherSuite = 0x0044 // RFC5932
|
||||||
|
TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA TLSCipherSuite = 0x0045 // RFC5932
|
||||||
|
TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA TLSCipherSuite = 0x0046 // RFC5932
|
||||||
|
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 TLSCipherSuite = 0x0067 // RFC5246
|
||||||
|
TLS_DH_DSS_WITH_AES_256_CBC_SHA256 TLSCipherSuite = 0x0068 // RFC5246
|
||||||
|
TLS_DH_RSA_WITH_AES_256_CBC_SHA256 TLSCipherSuite = 0x0069 // RFC5246
|
||||||
|
TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 TLSCipherSuite = 0x006A // RFC5246
|
||||||
|
TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 TLSCipherSuite = 0x006B // RFC5246
|
||||||
|
TLS_DH_anon_WITH_AES_128_CBC_SHA256 TLSCipherSuite = 0x006C // RFC5246
|
||||||
|
TLS_DH_anon_WITH_AES_256_CBC_SHA256 TLSCipherSuite = 0x006D // RFC5246
|
||||||
|
TLS_RSA_WITH_CAMELLIA_256_CBC_SHA TLSCipherSuite = 0x0084 // RFC5932
|
||||||
|
TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA TLSCipherSuite = 0x0085 // RFC5932
|
||||||
|
TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA TLSCipherSuite = 0x0086 // RFC5932
|
||||||
|
TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA TLSCipherSuite = 0x0087 // RFC5932
|
||||||
|
TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA TLSCipherSuite = 0x0088 // RFC5932
|
||||||
|
TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA TLSCipherSuite = 0x0089 // RFC5932
|
||||||
|
TLS_PSK_WITH_RC4_128_SHA TLSCipherSuite = 0x008A // RFC4279 RFC6347 RFC-ietf-tls-rfc8447bis-14
|
||||||
|
TLS_PSK_WITH_3DES_EDE_CBC_SHA TLSCipherSuite = 0x008B // RFC4279
|
||||||
|
TLS_PSK_WITH_AES_128_CBC_SHA TLSCipherSuite = 0x008C // RFC4279
|
||||||
|
TLS_PSK_WITH_AES_256_CBC_SHA TLSCipherSuite = 0x008D // RFC4279
|
||||||
|
TLS_DHE_PSK_WITH_RC4_128_SHA TLSCipherSuite = 0x008E // RFC4279 RFC6347
|
||||||
|
TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA TLSCipherSuite = 0x008F // RFC4279
|
||||||
|
TLS_DHE_PSK_WITH_AES_128_CBC_SHA TLSCipherSuite = 0x0090 // RFC4279
|
||||||
|
TLS_DHE_PSK_WITH_AES_256_CBC_SHA TLSCipherSuite = 0x0091 // RFC4279
|
||||||
|
TLS_RSA_PSK_WITH_RC4_128_SHA TLSCipherSuite = 0x0092 // RFC4279 RFC6347
|
||||||
|
TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA TLSCipherSuite = 0x0093 // RFC4279
|
||||||
|
TLS_RSA_PSK_WITH_AES_128_CBC_SHA TLSCipherSuite = 0x0094 // RFC4279
|
||||||
|
TLS_RSA_PSK_WITH_AES_256_CBC_SHA TLSCipherSuite = 0x0095 // RFC4279
|
||||||
|
TLS_RSA_WITH_SEED_CBC_SHA TLSCipherSuite = 0x0096 // RFC4162
|
||||||
|
TLS_DH_DSS_WITH_SEED_CBC_SHA TLSCipherSuite = 0x0097 // RFC4162
|
||||||
|
TLS_DH_RSA_WITH_SEED_CBC_SHA TLSCipherSuite = 0x0098 // RFC4162
|
||||||
|
TLS_DHE_DSS_WITH_SEED_CBC_SHA TLSCipherSuite = 0x0099 // RFC4162
|
||||||
|
TLS_DHE_RSA_WITH_SEED_CBC_SHA TLSCipherSuite = 0x009A // RFC4162
|
||||||
|
TLS_DH_anon_WITH_SEED_CBC_SHA TLSCipherSuite = 0x009B // RFC4162
|
||||||
|
TLS_RSA_WITH_AES_128_GCM_SHA256 TLSCipherSuite = 0x009C // RFC5288
|
||||||
|
TLS_RSA_WITH_AES_256_GCM_SHA384 TLSCipherSuite = 0x009D // RFC5288
|
||||||
|
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 TLSCipherSuite = 0x009E // RFC5288
|
||||||
|
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 TLSCipherSuite = 0x009F // RFC5288
|
||||||
|
TLS_DH_RSA_WITH_AES_128_GCM_SHA256 TLSCipherSuite = 0x00A0 // RFC5288
|
||||||
|
TLS_DH_RSA_WITH_AES_256_GCM_SHA384 TLSCipherSuite = 0x00A1 // RFC5288
|
||||||
|
TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 TLSCipherSuite = 0x00A2 // RFC5288
|
||||||
|
TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 TLSCipherSuite = 0x00A3 // RFC5288
|
||||||
|
TLS_DH_DSS_WITH_AES_128_GCM_SHA256 TLSCipherSuite = 0x00A4 // RFC5288
|
||||||
|
TLS_DH_DSS_WITH_AES_256_GCM_SHA384 TLSCipherSuite = 0x00A5 // RFC5288
|
||||||
|
TLS_DH_anon_WITH_AES_128_GCM_SHA256 TLSCipherSuite = 0x00A6 // RFC5288
|
||||||
|
TLS_DH_anon_WITH_AES_256_GCM_SHA384 TLSCipherSuite = 0x00A7 // RFC5288
|
||||||
|
TLS_PSK_WITH_AES_128_GCM_SHA256 TLSCipherSuite = 0x00A8 // RFC5487
|
||||||
|
TLS_PSK_WITH_AES_256_GCM_SHA384 TLSCipherSuite = 0x00A9 // RFC5487
|
||||||
|
TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 TLSCipherSuite = 0x00AA // RFC5487
|
||||||
|
TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 TLSCipherSuite = 0x00AB // RFC5487
|
||||||
|
TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 TLSCipherSuite = 0x00AC // RFC5487
|
||||||
|
TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 TLSCipherSuite = 0x00AD // RFC5487
|
||||||
|
TLS_PSK_WITH_AES_128_CBC_SHA256 TLSCipherSuite = 0x00AE // RFC5487
|
||||||
|
TLS_PSK_WITH_AES_256_CBC_SHA384 TLSCipherSuite = 0x00AF // RFC5487
|
||||||
|
TLS_PSK_WITH_NULL_SHA256 TLSCipherSuite = 0x00B0 // RFC5487 RFC-ietf-tls-rfc8447bis-14
|
||||||
|
TLS_PSK_WITH_NULL_SHA384 TLSCipherSuite = 0x00B1 // RFC5487 RFC-ietf-tls-rfc8447bis-14
|
||||||
|
TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 TLSCipherSuite = 0x00B2 // RFC5487
|
||||||
|
TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 TLSCipherSuite = 0x00B3 // RFC5487
|
||||||
|
TLS_DHE_PSK_WITH_NULL_SHA256 TLSCipherSuite = 0x00B4 // RFC5487
|
||||||
|
TLS_DHE_PSK_WITH_NULL_SHA384 TLSCipherSuite = 0x00B5 // RFC5487
|
||||||
|
TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 TLSCipherSuite = 0x00B6 // RFC5487
|
||||||
|
TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 TLSCipherSuite = 0x00B7 // RFC5487
|
||||||
|
TLS_RSA_PSK_WITH_NULL_SHA256 TLSCipherSuite = 0x00B8 // RFC5487
|
||||||
|
TLS_RSA_PSK_WITH_NULL_SHA384 TLSCipherSuite = 0x00B9 // RFC5487
|
||||||
|
TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 TLSCipherSuite = 0x00BA // RFC5932
|
||||||
|
TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 TLSCipherSuite = 0x00BB // RFC5932
|
||||||
|
TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 TLSCipherSuite = 0x00BC // RFC5932
|
||||||
|
TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 TLSCipherSuite = 0x00BD // RFC5932
|
||||||
|
TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 TLSCipherSuite = 0x00BE // RFC5932
|
||||||
|
TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256 TLSCipherSuite = 0x00BF // RFC5932
|
||||||
|
TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 TLSCipherSuite = 0x00C0 // RFC5932
|
||||||
|
TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 TLSCipherSuite = 0x00C1 // RFC5932
|
||||||
|
TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 TLSCipherSuite = 0x00C2 // RFC5932
|
||||||
|
TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 TLSCipherSuite = 0x00C3 // RFC5932
|
||||||
|
TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 TLSCipherSuite = 0x00C4 // RFC5932
|
||||||
|
TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256 TLSCipherSuite = 0x00C5 // RFC5932
|
||||||
|
TLS_SM4_GCM_SM3 TLSCipherSuite = 0x00C6 // RFC8998
|
||||||
|
TLS_SM4_CCM_SM3 TLSCipherSuite = 0x00C7 // RFC8998
|
||||||
|
TLS_EMPTY_RENEGOTIATION_INFO_SCSV TLSCipherSuite = 0x00FF
|
||||||
|
TLS_AES_128_GCM_SHA256 TLSCipherSuite = 0x1301 // RFC-ietf-tls-rfc8446bis-13
|
||||||
|
TLS_AES_256_GCM_SHA384 TLSCipherSuite = 0x1302 // RFC-ietf-tls-rfc8446bis-13
|
||||||
|
TLS_CHACHA20_POLY1305_SHA256 TLSCipherSuite = 0x1303 // RFC-ietf-tls-rfc8446bis-13
|
||||||
|
TLS_AES_128_CCM_SHA256 TLSCipherSuite = 0x1304 // RFC-ietf-tls-rfc8446bis-13
|
||||||
|
TLS_AES_128_CCM_8_SHA256 TLSCipherSuite = 0x1305 // RFC-ietf-tls-rfc8446bis-13 IESG Action 2018-08-16
|
||||||
|
TLS_AEGIS_256_SHA512 TLSCipherSuite = 0x1306 // draft-irtf-cfrg-aegis-aead-08]
|
||||||
|
TLS_AEGIS_128L_SHA256 TLSCipherSuite = 0x1307
|
||||||
|
TLS_FALLBACK_SCSV TLSCipherSuite = 0x5600
|
||||||
|
TLS_ECDH_ECDSA_WITH_NULL_SHA TLSCipherSuite = 0xC001 // RFC8422
|
||||||
|
TLS_ECDH_ECDSA_WITH_RC4_128_SHA TLSCipherSuite = 0xC002 // RFC8422 RFC6347
|
||||||
|
TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA TLSCipherSuite = 0xC003 // RFC8422
|
||||||
|
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA TLSCipherSuite = 0xC004 // RFC8422
|
||||||
|
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA TLSCipherSuite = 0xC005 // RFC8422
|
||||||
|
TLS_ECDHE_ECDSA_WITH_NULL_SHA TLSCipherSuite = 0xC006 // RFC8422 RFC-ietf-tls-rfc8447bis-14
|
||||||
|
TLS_ECDHE_ECDSA_WITH_RC4_128_SHA TLSCipherSuite = 0xC007 // RFC8422 RFC6347 RFC-ietf-tls-rfc8447bis-14
|
||||||
|
TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA TLSCipherSuite = 0xC008 // RFC8422
|
||||||
|
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA TLSCipherSuite = 0xC009 // RFC8422
|
||||||
|
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA TLSCipherSuite = 0xC00A // RFC8422
|
||||||
|
TLS_ECDH_RSA_WITH_NULL_SHA TLSCipherSuite = 0xC00B // RFC8422
|
||||||
|
TLS_ECDH_RSA_WITH_RC4_128_SHA TLSCipherSuite = 0xC00C // RFC8422 RFC6347
|
||||||
|
TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA TLSCipherSuite = 0xC00D // RFC8422
|
||||||
|
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA TLSCipherSuite = 0xC00E // RFC8422
|
||||||
|
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA TLSCipherSuite = 0xC00F // RFC8422
|
||||||
|
TLS_ECDHE_RSA_WITH_NULL_SHA TLSCipherSuite = 0xC010 // RFC8422 RFC-ietf-tls-rfc8447bis-14
|
||||||
|
TLS_ECDHE_RSA_WITH_RC4_128_SHA TLSCipherSuite = 0xC011 // RFC8422 RFC6347 RFC-ietf-tls-rfc8447bis-14
|
||||||
|
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA TLSCipherSuite = 0xC012 // RFC8422
|
||||||
|
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA TLSCipherSuite = 0xC013 // RFC8422
|
||||||
|
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA TLSCipherSuite = 0xC014 // RFC8422
|
||||||
|
TLS_ECDH_anon_WITH_NULL_SHA TLSCipherSuite = 0xC015 // RFC8422
|
||||||
|
TLS_ECDH_anon_WITH_RC4_128_SHA TLSCipherSuite = 0xC016 // RFC8422 RFC6347
|
||||||
|
TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA TLSCipherSuite = 0xC017 // RFC8422
|
||||||
|
TLS_ECDH_anon_WITH_AES_128_CBC_SHA TLSCipherSuite = 0xC018 // RFC8422
|
||||||
|
TLS_ECDH_anon_WITH_AES_256_CBC_SHA TLSCipherSuite = 0xC019 // RFC8422
|
||||||
|
TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA TLSCipherSuite = 0xC01A // RFC5054
|
||||||
|
TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA TLSCipherSuite = 0xC01B // RFC5054
|
||||||
|
TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA TLSCipherSuite = 0xC01C // RFC5054
|
||||||
|
TLS_SRP_SHA_WITH_AES_128_CBC_SHA TLSCipherSuite = 0xC01D // RFC5054
|
||||||
|
TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA TLSCipherSuite = 0xC01E // RFC5054
|
||||||
|
TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA TLSCipherSuite = 0xC01F // RFC5054
|
||||||
|
TLS_SRP_SHA_WITH_AES_256_CBC_SHA TLSCipherSuite = 0xC020 // RFC5054
|
||||||
|
TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA TLSCipherSuite = 0xC021 // RFC5054
|
||||||
|
TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA TLSCipherSuite = 0xC022 // RFC5054
|
||||||
|
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 TLSCipherSuite = 0xC023 // RFC5289
|
||||||
|
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 TLSCipherSuite = 0xC024 // RFC5289
|
||||||
|
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 TLSCipherSuite = 0xC025 // RFC5289
|
||||||
|
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 TLSCipherSuite = 0xC026 // RFC5289
|
||||||
|
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 TLSCipherSuite = 0xC027 // RFC5289
|
||||||
|
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 TLSCipherSuite = 0xC028 // RFC5289
|
||||||
|
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 TLSCipherSuite = 0xC029 // RFC5289
|
||||||
|
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 TLSCipherSuite = 0xC02A // RFC5289
|
||||||
|
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 TLSCipherSuite = 0xC02B // RFC5289
|
||||||
|
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 TLSCipherSuite = 0xC02C // RFC5289
|
||||||
|
TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 TLSCipherSuite = 0xC02D // RFC5289
|
||||||
|
TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 TLSCipherSuite = 0xC02E // RFC5289
|
||||||
|
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 TLSCipherSuite = 0xC02F // RFC5289
|
||||||
|
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 TLSCipherSuite = 0xC030 // RFC5289
|
||||||
|
TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 TLSCipherSuite = 0xC031 // RFC5289
|
||||||
|
TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 TLSCipherSuite = 0xC032 // RFC5289
|
||||||
|
TLS_ECDHE_PSK_WITH_RC4_128_SHA TLSCipherSuite = 0xC033 // RFC5489 RFC6347 RFC-ietf-tls-rfc8447bis-14
|
||||||
|
TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA TLSCipherSuite = 0xC034 // RFC5489
|
||||||
|
TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA TLSCipherSuite = 0xC035 // RFC5489
|
||||||
|
TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA TLSCipherSuite = 0xC036 // RFC5489
|
||||||
|
TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 TLSCipherSuite = 0xC037 // RFC5489
|
||||||
|
TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 TLSCipherSuite = 0xC038 // RFC5489
|
||||||
|
TLS_ECDHE_PSK_WITH_NULL_SHA TLSCipherSuite = 0xC039 // RFC5489 RFC-ietf-tls-rfc8447bis-14
|
||||||
|
TLS_ECDHE_PSK_WITH_NULL_SHA256 TLSCipherSuite = 0xC03A // RFC5489 RFC-ietf-tls-rfc8447bis-14
|
||||||
|
TLS_ECDHE_PSK_WITH_NULL_SHA384 TLSCipherSuite = 0xC03B // RFC5489 RFC-ietf-tls-rfc8447bis-14
|
||||||
|
TLS_RSA_WITH_ARIA_128_CBC_SHA256 TLSCipherSuite = 0xC03C // RFC6209
|
||||||
|
TLS_RSA_WITH_ARIA_256_CBC_SHA384 TLSCipherSuite = 0xC03D // RFC6209
|
||||||
|
TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256 TLSCipherSuite = 0xC03E // RFC6209
|
||||||
|
TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384 TLSCipherSuite = 0xC03F // RFC6209
|
||||||
|
TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256 TLSCipherSuite = 0xC040 // RFC6209
|
||||||
|
TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384 TLSCipherSuite = 0xC041 // RFC6209
|
||||||
|
TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256 TLSCipherSuite = 0xC042 // RFC6209
|
||||||
|
TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384 TLSCipherSuite = 0xC043 // RFC6209
|
||||||
|
TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 TLSCipherSuite = 0xC044 // RFC6209
|
||||||
|
TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 TLSCipherSuite = 0xC045 // RFC6209
|
||||||
|
TLS_DH_anon_WITH_ARIA_128_CBC_SHA256 TLSCipherSuite = 0xC046 // RFC6209
|
||||||
|
TLS_DH_anon_WITH_ARIA_256_CBC_SHA384 TLSCipherSuite = 0xC047 // RFC6209
|
||||||
|
TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 TLSCipherSuite = 0xC048 // RFC6209
|
||||||
|
TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 TLSCipherSuite = 0xC049 // RFC6209
|
||||||
|
TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 TLSCipherSuite = 0xC04A // RFC6209
|
||||||
|
TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 TLSCipherSuite = 0xC04B // RFC6209
|
||||||
|
TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 TLSCipherSuite = 0xC04C // RFC6209
|
||||||
|
TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 TLSCipherSuite = 0xC04D // RFC6209
|
||||||
|
TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 TLSCipherSuite = 0xC04E // RFC6209
|
||||||
|
TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 TLSCipherSuite = 0xC04F // RFC6209
|
||||||
|
TLS_RSA_WITH_ARIA_128_GCM_SHA256 TLSCipherSuite = 0xC050 // RFC6209
|
||||||
|
TLS_RSA_WITH_ARIA_256_GCM_SHA384 TLSCipherSuite = 0xC051 // RFC6209
|
||||||
|
TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256 TLSCipherSuite = 0xC052 // RFC6209
|
||||||
|
TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384 TLSCipherSuite = 0xC053 // RFC6209
|
||||||
|
TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256 TLSCipherSuite = 0xC054 // RFC6209
|
||||||
|
TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384 TLSCipherSuite = 0xC055 // RFC6209
|
||||||
|
TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256 TLSCipherSuite = 0xC056 // RFC6209
|
||||||
|
TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384 TLSCipherSuite = 0xC057 // RFC6209
|
||||||
|
TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256 TLSCipherSuite = 0xC058 // RFC6209
|
||||||
|
TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384 TLSCipherSuite = 0xC059 // RFC6209
|
||||||
|
TLS_DH_anon_WITH_ARIA_128_GCM_SHA256 TLSCipherSuite = 0xC05A // RFC6209
|
||||||
|
TLS_DH_anon_WITH_ARIA_256_GCM_SHA384 TLSCipherSuite = 0xC05B // RFC6209
|
||||||
|
TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 TLSCipherSuite = 0xC05C // RFC6209
|
||||||
|
TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 TLSCipherSuite = 0xC05D // RFC6209
|
||||||
|
TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 TLSCipherSuite = 0xC05E // RFC6209
|
||||||
|
TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 TLSCipherSuite = 0xC05F // RFC6209
|
||||||
|
TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 TLSCipherSuite = 0xC060 // RFC6209
|
||||||
|
TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 TLSCipherSuite = 0xC061 // RFC6209
|
||||||
|
TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 TLSCipherSuite = 0xC062 // RFC6209
|
||||||
|
TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 TLSCipherSuite = 0xC063 // RFC6209
|
||||||
|
TLS_PSK_WITH_ARIA_128_CBC_SHA256 TLSCipherSuite = 0xC064 // RFC6209
|
||||||
|
TLS_PSK_WITH_ARIA_256_CBC_SHA384 TLSCipherSuite = 0xC065 // RFC6209
|
||||||
|
TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 TLSCipherSuite = 0xC066 // RFC6209
|
||||||
|
TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 TLSCipherSuite = 0xC067 // RFC6209
|
||||||
|
TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 TLSCipherSuite = 0xC068 // RFC6209
|
||||||
|
TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 TLSCipherSuite = 0xC069 // RFC6209
|
||||||
|
TLS_PSK_WITH_ARIA_128_GCM_SHA256 TLSCipherSuite = 0xC06A // RFC6209
|
||||||
|
TLS_PSK_WITH_ARIA_256_GCM_SHA384 TLSCipherSuite = 0xC06B // RFC6209
|
||||||
|
TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256 TLSCipherSuite = 0xC06C // RFC6209
|
||||||
|
TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384 TLSCipherSuite = 0xC06D // RFC6209
|
||||||
|
TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 TLSCipherSuite = 0xC06E // RFC6209
|
||||||
|
TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 TLSCipherSuite = 0xC06F // RFC6209
|
||||||
|
TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 TLSCipherSuite = 0xC070 // RFC6209
|
||||||
|
TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 TLSCipherSuite = 0xC071 // RFC6209
|
||||||
|
TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 TLSCipherSuite = 0xC072 // RFC6367
|
||||||
|
TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 TLSCipherSuite = 0xC073 // RFC6367
|
||||||
|
TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 TLSCipherSuite = 0xC074 // RFC6367
|
||||||
|
TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 TLSCipherSuite = 0xC075 // RFC6367
|
||||||
|
TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 TLSCipherSuite = 0xC076 // RFC6367
|
||||||
|
TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 TLSCipherSuite = 0xC077 // RFC6367
|
||||||
|
TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 TLSCipherSuite = 0xC078 // RFC6367
|
||||||
|
TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 TLSCipherSuite = 0xC079 // RFC6367
|
||||||
|
TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 TLSCipherSuite = 0xC07A // RFC6367
|
||||||
|
TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 TLSCipherSuite = 0xC07B // RFC6367
|
||||||
|
TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 TLSCipherSuite = 0xC07C // RFC6367
|
||||||
|
TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 TLSCipherSuite = 0xC07D // RFC6367
|
||||||
|
TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256 TLSCipherSuite = 0xC07E // RFC6367
|
||||||
|
TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384 TLSCipherSuite = 0xC07F // RFC6367
|
||||||
|
TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256 TLSCipherSuite = 0xC080 // RFC6367
|
||||||
|
TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384 TLSCipherSuite = 0xC081 // RFC6367
|
||||||
|
TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256 TLSCipherSuite = 0xC082 // RFC6367
|
||||||
|
TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384 TLSCipherSuite = 0xC083 // RFC6367
|
||||||
|
TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256 TLSCipherSuite = 0xC084 // RFC6367
|
||||||
|
TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384 TLSCipherSuite = 0xC085 // RFC6367
|
||||||
|
TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 TLSCipherSuite = 0xC086 // RFC6367
|
||||||
|
TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 TLSCipherSuite = 0xC087 // RFC6367
|
||||||
|
TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 TLSCipherSuite = 0xC088 // RFC6367
|
||||||
|
TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 TLSCipherSuite = 0xC089 // RFC6367
|
||||||
|
TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 TLSCipherSuite = 0xC08A // RFC6367
|
||||||
|
TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 TLSCipherSuite = 0xC08B // RFC6367
|
||||||
|
TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 TLSCipherSuite = 0xC08C // RFC6367
|
||||||
|
TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 TLSCipherSuite = 0xC08D // RFC6367
|
||||||
|
TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 TLSCipherSuite = 0xC08E // RFC6367
|
||||||
|
TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 TLSCipherSuite = 0xC08F // RFC6367
|
||||||
|
TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 TLSCipherSuite = 0xC090 // RFC6367
|
||||||
|
TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 TLSCipherSuite = 0xC091 // RFC6367
|
||||||
|
TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 TLSCipherSuite = 0xC092 // RFC6367
|
||||||
|
TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 TLSCipherSuite = 0xC093 // RFC6367
|
||||||
|
TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 TLSCipherSuite = 0xC094 // RFC6367
|
||||||
|
TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 TLSCipherSuite = 0xC095 // RFC6367
|
||||||
|
TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 TLSCipherSuite = 0xC096 // RFC6367
|
||||||
|
TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 TLSCipherSuite = 0xC097 // RFC6367
|
||||||
|
TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 TLSCipherSuite = 0xC098 // RFC6367
|
||||||
|
TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 TLSCipherSuite = 0xC099 // RFC6367
|
||||||
|
TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 TLSCipherSuite = 0xC09A // RFC6367
|
||||||
|
TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 TLSCipherSuite = 0xC09B // RFC6367
|
||||||
|
TLS_RSA_WITH_AES_128_CCM TLSCipherSuite = 0xC09C // RFC6655
|
||||||
|
TLS_RSA_WITH_AES_256_CCM TLSCipherSuite = 0xC09D // RFC6655
|
||||||
|
TLS_DHE_RSA_WITH_AES_128_CCM TLSCipherSuite = 0xC09E // RFC6655
|
||||||
|
TLS_DHE_RSA_WITH_AES_256_CCM TLSCipherSuite = 0xC09F // RFC6655
|
||||||
|
TLS_RSA_WITH_AES_128_CCM_8 TLSCipherSuite = 0xC0A0 // RFC6655
|
||||||
|
TLS_RSA_WITH_AES_256_CCM_8 TLSCipherSuite = 0xC0A1 // RFC6655
|
||||||
|
TLS_DHE_RSA_WITH_AES_128_CCM_8 TLSCipherSuite = 0xC0A2 // RFC6655
|
||||||
|
TLS_DHE_RSA_WITH_AES_256_CCM_8 TLSCipherSuite = 0xC0A3 // RFC6655
|
||||||
|
TLS_PSK_WITH_AES_128_CCM TLSCipherSuite = 0xC0A4 // RFC6655
|
||||||
|
TLS_PSK_WITH_AES_256_CCM TLSCipherSuite = 0xC0A5 // RFC6655
|
||||||
|
TLS_DHE_PSK_WITH_AES_128_CCM TLSCipherSuite = 0xC0A6 // RFC6655
|
||||||
|
TLS_DHE_PSK_WITH_AES_256_CCM TLSCipherSuite = 0xC0A7 // RFC6655
|
||||||
|
TLS_PSK_WITH_AES_128_CCM_8 TLSCipherSuite = 0xC0A8 // RFC6655
|
||||||
|
TLS_PSK_WITH_AES_256_CCM_8 TLSCipherSuite = 0xC0A9 // RFC6655
|
||||||
|
TLS_PSK_DHE_WITH_AES_128_CCM_8 TLSCipherSuite = 0xC0AA // RFC6655
|
||||||
|
TLS_PSK_DHE_WITH_AES_256_CCM_8 TLSCipherSuite = 0xC0AB // RFC6655
|
||||||
|
TLS_ECDHE_ECDSA_WITH_AES_128_CCM TLSCipherSuite = 0xC0AC // RFC7251
|
||||||
|
TLS_ECDHE_ECDSA_WITH_AES_256_CCM TLSCipherSuite = 0xC0AD // RFC7251
|
||||||
|
TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 TLSCipherSuite = 0xC0AE // RFC7251
|
||||||
|
TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 TLSCipherSuite = 0xC0AF // RFC7251
|
||||||
|
TLS_ECCPWD_WITH_AES_128_GCM_SHA256 TLSCipherSuite = 0xC0B0 // RFC8492
|
||||||
|
TLS_ECCPWD_WITH_AES_256_GCM_SHA384 TLSCipherSuite = 0xC0B1 // RFC8492
|
||||||
|
TLS_ECCPWD_WITH_AES_128_CCM_SHA256 TLSCipherSuite = 0xC0B2 // RFC8492
|
||||||
|
TLS_ECCPWD_WITH_AES_256_CCM_SHA384 TLSCipherSuite = 0xC0B3 // RFC8492
|
||||||
|
TLS_SHA256_SHA256 TLSCipherSuite = 0xC0B4 // RFC9150 RFC-ietf-tls-rfc8447bis-14
|
||||||
|
TLS_SHA384_SHA384 TLSCipherSuite = 0xC0B5 // RFC9150 RFC-ietf-tls-rfc8447bis-14
|
||||||
|
TLS_GOSTR341112_256_WITH_KUZNYECHIK_CTR_OMAC TLSCipherSuite = 0xC100 // RFC9189
|
||||||
|
TLS_GOSTR341112_256_WITH_MAGMA_CTR_OMAC TLSCipherSuite = 0xC101 // RFC9189
|
||||||
|
TLS_GOSTR341112_256_WITH_28147_CNT_IMIT TLSCipherSuite = 0xC102 // RFC9189
|
||||||
|
TLS_GOSTR341112_256_WITH_KUZNYECHIK_MGM_L TLSCipherSuite = 0xC103 // RFC9367
|
||||||
|
TLS_GOSTR341112_256_WITH_MAGMA_MGM_L TLSCipherSuite = 0xC104 // RFC9367
|
||||||
|
TLS_GOSTR341112_256_WITH_KUZNYECHIK_MGM_S TLSCipherSuite = 0xC105 // RFC9367
|
||||||
|
TLS_GOSTR341112_256_WITH_MAGMA_MGM_S TLSCipherSuite = 0xC106 // RFC9367
|
||||||
|
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 TLSCipherSuite = 0xCCA8 // RFC7905
|
||||||
|
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 TLSCipherSuite = 0xCCA9 // RFC7905
|
||||||
|
TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 TLSCipherSuite = 0xCCAA // RFC7905
|
||||||
|
TLS_PSK_WITH_CHACHA20_POLY1305_SHA256 TLSCipherSuite = 0xCCAB // RFC7905
|
||||||
|
TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 TLSCipherSuite = 0xCCAC // RFC7905
|
||||||
|
TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 TLSCipherSuite = 0xCCAD // RFC7905
|
||||||
|
TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256 TLSCipherSuite = 0xCCAE // RFC7905
|
||||||
|
TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256 TLSCipherSuite = 0xD001 // RFC8442
|
||||||
|
TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384 TLSCipherSuite = 0xD002 // RFC8442
|
||||||
|
TLS_ECDHE_PSK_WITH_AES_128_CCM_8_SHA256 TLSCipherSuite = 0xD003 // RFC8442
|
||||||
|
TLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256 TLSCipherSuite = 0xD005
|
||||||
|
)
|
||||||
|
|
||||||
|
func TLSCipherSuiteName(suite TLSCipherSuite) string {
|
||||||
|
return suite.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// TLS compression methods
|
||||||
|
//
|
||||||
|
// See https://www.iana.org/assignments/comp-meth-ids/comp-meth-ids.xhtml
|
||||||
|
const (
|
||||||
|
TLS_COMPRESS_NULL uint8 = 0
|
||||||
|
TLS_COMPRESS_DEFLATE uint8 = 1
|
||||||
|
TLS_COMPRESS_LSZ uint8 = 64
|
||||||
|
)
|
||||||
|
|
||||||
|
var tlsCompressionMethodNames = map[uint8]string{
|
||||||
|
TLS_COMPRESS_NULL: "NULL",
|
||||||
|
TLS_COMPRESS_DEFLATE: "DEFLATE",
|
||||||
|
TLS_COMPRESS_LSZ: "LSZ",
|
||||||
|
}
|
||||||
|
|
||||||
|
func TLSCompressionMethodName(method uint8) string {
|
||||||
|
if s, ok := tlsCompressionMethodNames[method]; ok {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("0x%02X", method)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TLS signature scheme.
|
||||||
|
type TLSSignatureScheme uint16
|
||||||
|
|
||||||
|
// TLS signature schemes.
|
||||||
|
//
|
||||||
|
// See RFC 8446, Section 4.2.3
|
||||||
|
const (
|
||||||
|
// RSASSA-PKCS1-v1_5 algorithms.
|
||||||
|
PKCS1WithSHA256 TLSSignatureScheme = 0x0401
|
||||||
|
PKCS1WithSHA384 TLSSignatureScheme = 0x0501
|
||||||
|
PKCS1WithSHA512 TLSSignatureScheme = 0x0601
|
||||||
|
|
||||||
|
// RSASSA-PSS algorithms with public key OID rsaEncryption.
|
||||||
|
PSSWithSHA256 TLSSignatureScheme = 0x0804
|
||||||
|
PSSWithSHA384 TLSSignatureScheme = 0x0805
|
||||||
|
PSSWithSHA512 TLSSignatureScheme = 0x0806
|
||||||
|
|
||||||
|
// ECDSA algorithms. Only constrained to a specific curve in TLS 1.3.
|
||||||
|
ECDSAWithP256AndSHA256 TLSSignatureScheme = 0x0403
|
||||||
|
ECDSAWithP384AndSHA384 TLSSignatureScheme = 0x0503
|
||||||
|
ECDSAWithP521AndSHA512 TLSSignatureScheme = 0x0603
|
||||||
|
|
||||||
|
// EdDSA algorithms.
|
||||||
|
Ed25519 TLSSignatureScheme = 0x0807
|
||||||
|
|
||||||
|
// Legacy signature and hash algorithms for TLS 1.2.
|
||||||
|
PKCS1WithSHA1 TLSSignatureScheme = 0x0201
|
||||||
|
ECDSAWithSHA1 TLSSignatureScheme = 0x0203
|
||||||
|
)
|
786
tls_const_string.go
Normal file
786
tls_const_string.go
Normal file
@@ -0,0 +1,786 @@
|
|||||||
|
// Code generated by "stringer -linecomment -type=TLSCipherSuite,TLSSignatureScheme -output=tls_const_string.go"; DO NOT EDIT.
|
||||||
|
|
||||||
|
package dpi
|
||||||
|
|
||||||
|
import "strconv"
|
||||||
|
|
||||||
|
func _() {
|
||||||
|
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||||
|
// Re-run the stringer command to generate them again.
|
||||||
|
var x [1]struct{}
|
||||||
|
_ = x[TLS_NULL_WITH_NULL_NULL-0]
|
||||||
|
_ = x[TLS_RSA_WITH_NULL_MD5-1]
|
||||||
|
_ = x[TLS_RSA_WITH_NULL_SHA-2]
|
||||||
|
_ = x[TLS_RSA_EXPORT_WITH_RC4_40_MD5-3]
|
||||||
|
_ = x[TLS_RSA_WITH_RC4_128_MD5-4]
|
||||||
|
_ = x[TLS_RSA_WITH_RC4_128_SHA-5]
|
||||||
|
_ = x[TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5-6]
|
||||||
|
_ = x[TLS_RSA_WITH_IDEA_CBC_SHA-7]
|
||||||
|
_ = x[TLS_RSA_EXPORT_WITH_DES40_CBC_SHA-8]
|
||||||
|
_ = x[TLS_RSA_WITH_DES_CBC_SHA-9]
|
||||||
|
_ = x[TLS_RSA_WITH_3DES_EDE_CBC_SHA-10]
|
||||||
|
_ = x[TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA-11]
|
||||||
|
_ = x[TLS_DH_DSS_WITH_DES_CBC_SHA-12]
|
||||||
|
_ = x[TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA-13]
|
||||||
|
_ = x[TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA-14]
|
||||||
|
_ = x[TLS_DH_RSA_WITH_DES_CBC_SHA-15]
|
||||||
|
_ = x[TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA-16]
|
||||||
|
_ = x[TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA-17]
|
||||||
|
_ = x[TLS_DHE_DSS_WITH_DES_CBC_SHA-18]
|
||||||
|
_ = x[TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA-19]
|
||||||
|
_ = x[TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA-20]
|
||||||
|
_ = x[TLS_DHE_RSA_WITH_DES_CBC_SHA-21]
|
||||||
|
_ = x[TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA-22]
|
||||||
|
_ = x[TLS_DH_anon_EXPORT_WITH_RC4_40_MD5-23]
|
||||||
|
_ = x[TLS_DH_anon_WITH_RC4_128_MD5-24]
|
||||||
|
_ = x[TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA-25]
|
||||||
|
_ = x[TLS_DH_anon_WITH_DES_CBC_SHA-26]
|
||||||
|
_ = x[TLS_DH_anon_WITH_3DES_EDE_CBC_SHA-27]
|
||||||
|
_ = x[TLS_KRB5_WITH_DES_CBC_SHA-30]
|
||||||
|
_ = x[TLS_KRB5_WITH_3DES_EDE_CBC_SHA-31]
|
||||||
|
_ = x[TLS_KRB5_WITH_RC4_128_SHA-32]
|
||||||
|
_ = x[TLS_KRB5_WITH_IDEA_CBC_SHA-33]
|
||||||
|
_ = x[TLS_KRB5_WITH_DES_CBC_MD5-34]
|
||||||
|
_ = x[TLS_KRB5_WITH_3DES_EDE_CBC_MD5-35]
|
||||||
|
_ = x[TLS_KRB5_WITH_RC4_128_MD5-36]
|
||||||
|
_ = x[TLS_KRB5_WITH_IDEA_CBC_MD5-37]
|
||||||
|
_ = x[TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA-38]
|
||||||
|
_ = x[TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA-39]
|
||||||
|
_ = x[TLS_KRB5_EXPORT_WITH_RC4_40_SHA-40]
|
||||||
|
_ = x[TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5-41]
|
||||||
|
_ = x[TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5-42]
|
||||||
|
_ = x[TLS_KRB5_EXPORT_WITH_RC4_40_MD5-43]
|
||||||
|
_ = x[TLS_PSK_WITH_NULL_SHA-44]
|
||||||
|
_ = x[TLS_DHE_PSK_WITH_NULL_SHA-45]
|
||||||
|
_ = x[TLS_RSA_PSK_WITH_NULL_SHA-46]
|
||||||
|
_ = x[TLS_RSA_WITH_AES_128_CBC_SHA-47]
|
||||||
|
_ = x[TLS_DH_DSS_WITH_AES_128_CBC_SHA-48]
|
||||||
|
_ = x[TLS_DH_RSA_WITH_AES_128_CBC_SHA-49]
|
||||||
|
_ = x[TLS_DHE_DSS_WITH_AES_128_CBC_SHA-50]
|
||||||
|
_ = x[TLS_DHE_RSA_WITH_AES_128_CBC_SHA-51]
|
||||||
|
_ = x[TLS_DH_anon_WITH_AES_128_CBC_SHA-52]
|
||||||
|
_ = x[TLS_RSA_WITH_AES_256_CBC_SHA-53]
|
||||||
|
_ = x[TLS_DH_DSS_WITH_AES_256_CBC_SHA-54]
|
||||||
|
_ = x[TLS_DH_RSA_WITH_AES_256_CBC_SHA-55]
|
||||||
|
_ = x[TLS_DHE_DSS_WITH_AES_256_CBC_SHA-56]
|
||||||
|
_ = x[TLS_DHE_RSA_WITH_AES_256_CBC_SHA-57]
|
||||||
|
_ = x[TLS_DH_anon_WITH_AES_256_CBC_SHA-58]
|
||||||
|
_ = x[TLS_RSA_WITH_NULL_SHA256-59]
|
||||||
|
_ = x[TLS_RSA_WITH_AES_128_CBC_SHA256-60]
|
||||||
|
_ = x[TLS_RSA_WITH_AES_256_CBC_SHA256-61]
|
||||||
|
_ = x[TLS_DH_DSS_WITH_AES_128_CBC_SHA256-62]
|
||||||
|
_ = x[TLS_DH_RSA_WITH_AES_128_CBC_SHA256-63]
|
||||||
|
_ = x[TLS_DHE_DSS_WITH_AES_128_CBC_SHA256-64]
|
||||||
|
_ = x[TLS_RSA_WITH_CAMELLIA_128_CBC_SHA-65]
|
||||||
|
_ = x[TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA-66]
|
||||||
|
_ = x[TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA-67]
|
||||||
|
_ = x[TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA-68]
|
||||||
|
_ = x[TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA-69]
|
||||||
|
_ = x[TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA-70]
|
||||||
|
_ = x[TLS_DHE_RSA_WITH_AES_128_CBC_SHA256-103]
|
||||||
|
_ = x[TLS_DH_DSS_WITH_AES_256_CBC_SHA256-104]
|
||||||
|
_ = x[TLS_DH_RSA_WITH_AES_256_CBC_SHA256-105]
|
||||||
|
_ = x[TLS_DHE_DSS_WITH_AES_256_CBC_SHA256-106]
|
||||||
|
_ = x[TLS_DHE_RSA_WITH_AES_256_CBC_SHA256-107]
|
||||||
|
_ = x[TLS_DH_anon_WITH_AES_128_CBC_SHA256-108]
|
||||||
|
_ = x[TLS_DH_anon_WITH_AES_256_CBC_SHA256-109]
|
||||||
|
_ = x[TLS_RSA_WITH_CAMELLIA_256_CBC_SHA-132]
|
||||||
|
_ = x[TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA-133]
|
||||||
|
_ = x[TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA-134]
|
||||||
|
_ = x[TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA-135]
|
||||||
|
_ = x[TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA-136]
|
||||||
|
_ = x[TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA-137]
|
||||||
|
_ = x[TLS_PSK_WITH_RC4_128_SHA-138]
|
||||||
|
_ = x[TLS_PSK_WITH_3DES_EDE_CBC_SHA-139]
|
||||||
|
_ = x[TLS_PSK_WITH_AES_128_CBC_SHA-140]
|
||||||
|
_ = x[TLS_PSK_WITH_AES_256_CBC_SHA-141]
|
||||||
|
_ = x[TLS_DHE_PSK_WITH_RC4_128_SHA-142]
|
||||||
|
_ = x[TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA-143]
|
||||||
|
_ = x[TLS_DHE_PSK_WITH_AES_128_CBC_SHA-144]
|
||||||
|
_ = x[TLS_DHE_PSK_WITH_AES_256_CBC_SHA-145]
|
||||||
|
_ = x[TLS_RSA_PSK_WITH_RC4_128_SHA-146]
|
||||||
|
_ = x[TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA-147]
|
||||||
|
_ = x[TLS_RSA_PSK_WITH_AES_128_CBC_SHA-148]
|
||||||
|
_ = x[TLS_RSA_PSK_WITH_AES_256_CBC_SHA-149]
|
||||||
|
_ = x[TLS_RSA_WITH_SEED_CBC_SHA-150]
|
||||||
|
_ = x[TLS_DH_DSS_WITH_SEED_CBC_SHA-151]
|
||||||
|
_ = x[TLS_DH_RSA_WITH_SEED_CBC_SHA-152]
|
||||||
|
_ = x[TLS_DHE_DSS_WITH_SEED_CBC_SHA-153]
|
||||||
|
_ = x[TLS_DHE_RSA_WITH_SEED_CBC_SHA-154]
|
||||||
|
_ = x[TLS_DH_anon_WITH_SEED_CBC_SHA-155]
|
||||||
|
_ = x[TLS_RSA_WITH_AES_128_GCM_SHA256-156]
|
||||||
|
_ = x[TLS_RSA_WITH_AES_256_GCM_SHA384-157]
|
||||||
|
_ = x[TLS_DHE_RSA_WITH_AES_128_GCM_SHA256-158]
|
||||||
|
_ = x[TLS_DHE_RSA_WITH_AES_256_GCM_SHA384-159]
|
||||||
|
_ = x[TLS_DH_RSA_WITH_AES_128_GCM_SHA256-160]
|
||||||
|
_ = x[TLS_DH_RSA_WITH_AES_256_GCM_SHA384-161]
|
||||||
|
_ = x[TLS_DHE_DSS_WITH_AES_128_GCM_SHA256-162]
|
||||||
|
_ = x[TLS_DHE_DSS_WITH_AES_256_GCM_SHA384-163]
|
||||||
|
_ = x[TLS_DH_DSS_WITH_AES_128_GCM_SHA256-164]
|
||||||
|
_ = x[TLS_DH_DSS_WITH_AES_256_GCM_SHA384-165]
|
||||||
|
_ = x[TLS_DH_anon_WITH_AES_128_GCM_SHA256-166]
|
||||||
|
_ = x[TLS_DH_anon_WITH_AES_256_GCM_SHA384-167]
|
||||||
|
_ = x[TLS_PSK_WITH_AES_128_GCM_SHA256-168]
|
||||||
|
_ = x[TLS_PSK_WITH_AES_256_GCM_SHA384-169]
|
||||||
|
_ = x[TLS_DHE_PSK_WITH_AES_128_GCM_SHA256-170]
|
||||||
|
_ = x[TLS_DHE_PSK_WITH_AES_256_GCM_SHA384-171]
|
||||||
|
_ = x[TLS_RSA_PSK_WITH_AES_128_GCM_SHA256-172]
|
||||||
|
_ = x[TLS_RSA_PSK_WITH_AES_256_GCM_SHA384-173]
|
||||||
|
_ = x[TLS_PSK_WITH_AES_128_CBC_SHA256-174]
|
||||||
|
_ = x[TLS_PSK_WITH_AES_256_CBC_SHA384-175]
|
||||||
|
_ = x[TLS_PSK_WITH_NULL_SHA256-176]
|
||||||
|
_ = x[TLS_PSK_WITH_NULL_SHA384-177]
|
||||||
|
_ = x[TLS_DHE_PSK_WITH_AES_128_CBC_SHA256-178]
|
||||||
|
_ = x[TLS_DHE_PSK_WITH_AES_256_CBC_SHA384-179]
|
||||||
|
_ = x[TLS_DHE_PSK_WITH_NULL_SHA256-180]
|
||||||
|
_ = x[TLS_DHE_PSK_WITH_NULL_SHA384-181]
|
||||||
|
_ = x[TLS_RSA_PSK_WITH_AES_128_CBC_SHA256-182]
|
||||||
|
_ = x[TLS_RSA_PSK_WITH_AES_256_CBC_SHA384-183]
|
||||||
|
_ = x[TLS_RSA_PSK_WITH_NULL_SHA256-184]
|
||||||
|
_ = x[TLS_RSA_PSK_WITH_NULL_SHA384-185]
|
||||||
|
_ = x[TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256-186]
|
||||||
|
_ = x[TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256-187]
|
||||||
|
_ = x[TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256-188]
|
||||||
|
_ = x[TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256-189]
|
||||||
|
_ = x[TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256-190]
|
||||||
|
_ = x[TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256-191]
|
||||||
|
_ = x[TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256-192]
|
||||||
|
_ = x[TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256-193]
|
||||||
|
_ = x[TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256-194]
|
||||||
|
_ = x[TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256-195]
|
||||||
|
_ = x[TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256-196]
|
||||||
|
_ = x[TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256-197]
|
||||||
|
_ = x[TLS_SM4_GCM_SM3-198]
|
||||||
|
_ = x[TLS_SM4_CCM_SM3-199]
|
||||||
|
_ = x[TLS_EMPTY_RENEGOTIATION_INFO_SCSV-255]
|
||||||
|
_ = x[TLS_AES_128_GCM_SHA256-4865]
|
||||||
|
_ = x[TLS_AES_256_GCM_SHA384-4866]
|
||||||
|
_ = x[TLS_CHACHA20_POLY1305_SHA256-4867]
|
||||||
|
_ = x[TLS_AES_128_CCM_SHA256-4868]
|
||||||
|
_ = x[TLS_AES_128_CCM_8_SHA256-4869]
|
||||||
|
_ = x[TLS_AEGIS_256_SHA512-4870]
|
||||||
|
_ = x[TLS_AEGIS_128L_SHA256-4871]
|
||||||
|
_ = x[TLS_FALLBACK_SCSV-22016]
|
||||||
|
_ = x[TLS_ECDH_ECDSA_WITH_NULL_SHA-49153]
|
||||||
|
_ = x[TLS_ECDH_ECDSA_WITH_RC4_128_SHA-49154]
|
||||||
|
_ = x[TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA-49155]
|
||||||
|
_ = x[TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA-49156]
|
||||||
|
_ = x[TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA-49157]
|
||||||
|
_ = x[TLS_ECDHE_ECDSA_WITH_NULL_SHA-49158]
|
||||||
|
_ = x[TLS_ECDHE_ECDSA_WITH_RC4_128_SHA-49159]
|
||||||
|
_ = x[TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA-49160]
|
||||||
|
_ = x[TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA-49161]
|
||||||
|
_ = x[TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA-49162]
|
||||||
|
_ = x[TLS_ECDH_RSA_WITH_NULL_SHA-49163]
|
||||||
|
_ = x[TLS_ECDH_RSA_WITH_RC4_128_SHA-49164]
|
||||||
|
_ = x[TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA-49165]
|
||||||
|
_ = x[TLS_ECDH_RSA_WITH_AES_128_CBC_SHA-49166]
|
||||||
|
_ = x[TLS_ECDH_RSA_WITH_AES_256_CBC_SHA-49167]
|
||||||
|
_ = x[TLS_ECDHE_RSA_WITH_NULL_SHA-49168]
|
||||||
|
_ = x[TLS_ECDHE_RSA_WITH_RC4_128_SHA-49169]
|
||||||
|
_ = x[TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA-49170]
|
||||||
|
_ = x[TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA-49171]
|
||||||
|
_ = x[TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA-49172]
|
||||||
|
_ = x[TLS_ECDH_anon_WITH_NULL_SHA-49173]
|
||||||
|
_ = x[TLS_ECDH_anon_WITH_RC4_128_SHA-49174]
|
||||||
|
_ = x[TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA-49175]
|
||||||
|
_ = x[TLS_ECDH_anon_WITH_AES_128_CBC_SHA-49176]
|
||||||
|
_ = x[TLS_ECDH_anon_WITH_AES_256_CBC_SHA-49177]
|
||||||
|
_ = x[TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA-49178]
|
||||||
|
_ = x[TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA-49179]
|
||||||
|
_ = x[TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA-49180]
|
||||||
|
_ = x[TLS_SRP_SHA_WITH_AES_128_CBC_SHA-49181]
|
||||||
|
_ = x[TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA-49182]
|
||||||
|
_ = x[TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA-49183]
|
||||||
|
_ = x[TLS_SRP_SHA_WITH_AES_256_CBC_SHA-49184]
|
||||||
|
_ = x[TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA-49185]
|
||||||
|
_ = x[TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA-49186]
|
||||||
|
_ = x[TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256-49187]
|
||||||
|
_ = x[TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384-49188]
|
||||||
|
_ = x[TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256-49189]
|
||||||
|
_ = x[TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384-49190]
|
||||||
|
_ = x[TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256-49191]
|
||||||
|
_ = x[TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384-49192]
|
||||||
|
_ = x[TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256-49193]
|
||||||
|
_ = x[TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384-49194]
|
||||||
|
_ = x[TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256-49195]
|
||||||
|
_ = x[TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384-49196]
|
||||||
|
_ = x[TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256-49197]
|
||||||
|
_ = x[TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384-49198]
|
||||||
|
_ = x[TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256-49199]
|
||||||
|
_ = x[TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384-49200]
|
||||||
|
_ = x[TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256-49201]
|
||||||
|
_ = x[TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384-49202]
|
||||||
|
_ = x[TLS_ECDHE_PSK_WITH_RC4_128_SHA-49203]
|
||||||
|
_ = x[TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA-49204]
|
||||||
|
_ = x[TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA-49205]
|
||||||
|
_ = x[TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA-49206]
|
||||||
|
_ = x[TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256-49207]
|
||||||
|
_ = x[TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384-49208]
|
||||||
|
_ = x[TLS_ECDHE_PSK_WITH_NULL_SHA-49209]
|
||||||
|
_ = x[TLS_ECDHE_PSK_WITH_NULL_SHA256-49210]
|
||||||
|
_ = x[TLS_ECDHE_PSK_WITH_NULL_SHA384-49211]
|
||||||
|
_ = x[TLS_RSA_WITH_ARIA_128_CBC_SHA256-49212]
|
||||||
|
_ = x[TLS_RSA_WITH_ARIA_256_CBC_SHA384-49213]
|
||||||
|
_ = x[TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256-49214]
|
||||||
|
_ = x[TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384-49215]
|
||||||
|
_ = x[TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256-49216]
|
||||||
|
_ = x[TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384-49217]
|
||||||
|
_ = x[TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256-49218]
|
||||||
|
_ = x[TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384-49219]
|
||||||
|
_ = x[TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256-49220]
|
||||||
|
_ = x[TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384-49221]
|
||||||
|
_ = x[TLS_DH_anon_WITH_ARIA_128_CBC_SHA256-49222]
|
||||||
|
_ = x[TLS_DH_anon_WITH_ARIA_256_CBC_SHA384-49223]
|
||||||
|
_ = x[TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256-49224]
|
||||||
|
_ = x[TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384-49225]
|
||||||
|
_ = x[TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256-49226]
|
||||||
|
_ = x[TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384-49227]
|
||||||
|
_ = x[TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256-49228]
|
||||||
|
_ = x[TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384-49229]
|
||||||
|
_ = x[TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256-49230]
|
||||||
|
_ = x[TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384-49231]
|
||||||
|
_ = x[TLS_RSA_WITH_ARIA_128_GCM_SHA256-49232]
|
||||||
|
_ = x[TLS_RSA_WITH_ARIA_256_GCM_SHA384-49233]
|
||||||
|
_ = x[TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256-49234]
|
||||||
|
_ = x[TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384-49235]
|
||||||
|
_ = x[TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256-49236]
|
||||||
|
_ = x[TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384-49237]
|
||||||
|
_ = x[TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256-49238]
|
||||||
|
_ = x[TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384-49239]
|
||||||
|
_ = x[TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256-49240]
|
||||||
|
_ = x[TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384-49241]
|
||||||
|
_ = x[TLS_DH_anon_WITH_ARIA_128_GCM_SHA256-49242]
|
||||||
|
_ = x[TLS_DH_anon_WITH_ARIA_256_GCM_SHA384-49243]
|
||||||
|
_ = x[TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256-49244]
|
||||||
|
_ = x[TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384-49245]
|
||||||
|
_ = x[TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256-49246]
|
||||||
|
_ = x[TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384-49247]
|
||||||
|
_ = x[TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256-49248]
|
||||||
|
_ = x[TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384-49249]
|
||||||
|
_ = x[TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256-49250]
|
||||||
|
_ = x[TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384-49251]
|
||||||
|
_ = x[TLS_PSK_WITH_ARIA_128_CBC_SHA256-49252]
|
||||||
|
_ = x[TLS_PSK_WITH_ARIA_256_CBC_SHA384-49253]
|
||||||
|
_ = x[TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256-49254]
|
||||||
|
_ = x[TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384-49255]
|
||||||
|
_ = x[TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256-49256]
|
||||||
|
_ = x[TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384-49257]
|
||||||
|
_ = x[TLS_PSK_WITH_ARIA_128_GCM_SHA256-49258]
|
||||||
|
_ = x[TLS_PSK_WITH_ARIA_256_GCM_SHA384-49259]
|
||||||
|
_ = x[TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256-49260]
|
||||||
|
_ = x[TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384-49261]
|
||||||
|
_ = x[TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256-49262]
|
||||||
|
_ = x[TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384-49263]
|
||||||
|
_ = x[TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256-49264]
|
||||||
|
_ = x[TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384-49265]
|
||||||
|
_ = x[TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256-49266]
|
||||||
|
_ = x[TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384-49267]
|
||||||
|
_ = x[TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256-49268]
|
||||||
|
_ = x[TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384-49269]
|
||||||
|
_ = x[TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256-49270]
|
||||||
|
_ = x[TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384-49271]
|
||||||
|
_ = x[TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256-49272]
|
||||||
|
_ = x[TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384-49273]
|
||||||
|
_ = x[TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256-49274]
|
||||||
|
_ = x[TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384-49275]
|
||||||
|
_ = x[TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256-49276]
|
||||||
|
_ = x[TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384-49277]
|
||||||
|
_ = x[TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256-49278]
|
||||||
|
_ = x[TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384-49279]
|
||||||
|
_ = x[TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256-49280]
|
||||||
|
_ = x[TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384-49281]
|
||||||
|
_ = x[TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256-49282]
|
||||||
|
_ = x[TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384-49283]
|
||||||
|
_ = x[TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256-49284]
|
||||||
|
_ = x[TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384-49285]
|
||||||
|
_ = x[TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256-49286]
|
||||||
|
_ = x[TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384-49287]
|
||||||
|
_ = x[TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256-49288]
|
||||||
|
_ = x[TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384-49289]
|
||||||
|
_ = x[TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256-49290]
|
||||||
|
_ = x[TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384-49291]
|
||||||
|
_ = x[TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256-49292]
|
||||||
|
_ = x[TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384-49293]
|
||||||
|
_ = x[TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256-49294]
|
||||||
|
_ = x[TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384-49295]
|
||||||
|
_ = x[TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256-49296]
|
||||||
|
_ = x[TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384-49297]
|
||||||
|
_ = x[TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256-49298]
|
||||||
|
_ = x[TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384-49299]
|
||||||
|
_ = x[TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256-49300]
|
||||||
|
_ = x[TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384-49301]
|
||||||
|
_ = x[TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256-49302]
|
||||||
|
_ = x[TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384-49303]
|
||||||
|
_ = x[TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256-49304]
|
||||||
|
_ = x[TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384-49305]
|
||||||
|
_ = x[TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256-49306]
|
||||||
|
_ = x[TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384-49307]
|
||||||
|
_ = x[TLS_RSA_WITH_AES_128_CCM-49308]
|
||||||
|
_ = x[TLS_RSA_WITH_AES_256_CCM-49309]
|
||||||
|
_ = x[TLS_DHE_RSA_WITH_AES_128_CCM-49310]
|
||||||
|
_ = x[TLS_DHE_RSA_WITH_AES_256_CCM-49311]
|
||||||
|
_ = x[TLS_RSA_WITH_AES_128_CCM_8-49312]
|
||||||
|
_ = x[TLS_RSA_WITH_AES_256_CCM_8-49313]
|
||||||
|
_ = x[TLS_DHE_RSA_WITH_AES_128_CCM_8-49314]
|
||||||
|
_ = x[TLS_DHE_RSA_WITH_AES_256_CCM_8-49315]
|
||||||
|
_ = x[TLS_PSK_WITH_AES_128_CCM-49316]
|
||||||
|
_ = x[TLS_PSK_WITH_AES_256_CCM-49317]
|
||||||
|
_ = x[TLS_DHE_PSK_WITH_AES_128_CCM-49318]
|
||||||
|
_ = x[TLS_DHE_PSK_WITH_AES_256_CCM-49319]
|
||||||
|
_ = x[TLS_PSK_WITH_AES_128_CCM_8-49320]
|
||||||
|
_ = x[TLS_PSK_WITH_AES_256_CCM_8-49321]
|
||||||
|
_ = x[TLS_PSK_DHE_WITH_AES_128_CCM_8-49322]
|
||||||
|
_ = x[TLS_PSK_DHE_WITH_AES_256_CCM_8-49323]
|
||||||
|
_ = x[TLS_ECDHE_ECDSA_WITH_AES_128_CCM-49324]
|
||||||
|
_ = x[TLS_ECDHE_ECDSA_WITH_AES_256_CCM-49325]
|
||||||
|
_ = x[TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8-49326]
|
||||||
|
_ = x[TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8-49327]
|
||||||
|
_ = x[TLS_ECCPWD_WITH_AES_128_GCM_SHA256-49328]
|
||||||
|
_ = x[TLS_ECCPWD_WITH_AES_256_GCM_SHA384-49329]
|
||||||
|
_ = x[TLS_ECCPWD_WITH_AES_128_CCM_SHA256-49330]
|
||||||
|
_ = x[TLS_ECCPWD_WITH_AES_256_CCM_SHA384-49331]
|
||||||
|
_ = x[TLS_SHA256_SHA256-49332]
|
||||||
|
_ = x[TLS_SHA384_SHA384-49333]
|
||||||
|
_ = x[TLS_GOSTR341112_256_WITH_KUZNYECHIK_CTR_OMAC-49408]
|
||||||
|
_ = x[TLS_GOSTR341112_256_WITH_MAGMA_CTR_OMAC-49409]
|
||||||
|
_ = x[TLS_GOSTR341112_256_WITH_28147_CNT_IMIT-49410]
|
||||||
|
_ = x[TLS_GOSTR341112_256_WITH_KUZNYECHIK_MGM_L-49411]
|
||||||
|
_ = x[TLS_GOSTR341112_256_WITH_MAGMA_MGM_L-49412]
|
||||||
|
_ = x[TLS_GOSTR341112_256_WITH_KUZNYECHIK_MGM_S-49413]
|
||||||
|
_ = x[TLS_GOSTR341112_256_WITH_MAGMA_MGM_S-49414]
|
||||||
|
_ = x[TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256-52392]
|
||||||
|
_ = x[TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256-52393]
|
||||||
|
_ = x[TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256-52394]
|
||||||
|
_ = x[TLS_PSK_WITH_CHACHA20_POLY1305_SHA256-52395]
|
||||||
|
_ = x[TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256-52396]
|
||||||
|
_ = x[TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256-52397]
|
||||||
|
_ = x[TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256-52398]
|
||||||
|
_ = x[TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256-53249]
|
||||||
|
_ = x[TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384-53250]
|
||||||
|
_ = x[TLS_ECDHE_PSK_WITH_AES_128_CCM_8_SHA256-53251]
|
||||||
|
_ = x[TLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256-53253]
|
||||||
|
}
|
||||||
|
|
||||||
|
const _TLSCipherSuite_name = "TLS_NULL_WITH_NULL_NULLRFC5246RFC5246RFC4346 RFC6347RFC5246 RFC6347RFC5246 RFC6347RFC4346RFC8996RFC4346RFC8996RFC5246RFC4346RFC8996RFC5246RFC4346RFC8996RFC5246RFC4346RFC8996RFC5246RFC4346RFC8996RFC5246RFC4346 RFC6347RFC5246 RFC6347RFC4346RFC8996RFC5246RFC2712 RFC-ietf-tls-rfc8447bis-14RFC2712RFC2712 RFC6347 RFC-ietf-tls-rfc8447bis-14RFC2712 RFC-ietf-tls-rfc8447bis-14RFC2712 RFC-ietf-tls-rfc8447bis-14RFC2712RFC2712 RFC6347 RFC-ietf-tls-rfc8447bis-14RFC2712 RFC-ietf-tls-rfc8447bis-14RFC2712 RFC-ietf-tls-rfc8447bis-14RFC2712 RFC-ietf-tls-rfc8447bis-14RFC2712 RFC6347 RFC-ietf-tls-rfc8447bis-14RFC2712 RFC-ietf-tls-rfc8447bis-14RFC2712 RFC-ietf-tls-rfc8447bis-14RFC2712 RFC6347 RFC-ietf-tls-rfc8447bis-14RFC4785 RFC-ietf-tls-rfc8447bis-14RFC4785RFC4785RFC5246RFC5246RFC5246RFC5246RFC5246RFC5246RFC5246RFC5246RFC5246RFC5246RFC5246RFC5246RFC5246RFC5246RFC5246RFC5246RFC5246RFC5246RFC5932RFC5932RFC5932RFC5932RFC5932RFC5932RFC5246RFC5246RFC5246RFC5246RFC5246RFC5246RFC5246RFC5932RFC5932RFC5932RFC5932RFC5932RFC5932RFC4279 RFC6347 RFC-ietf-tls-rfc8447bis-14RFC4279RFC4279RFC4279RFC4279 RFC6347RFC4279RFC4279RFC4279RFC4279 RFC6347RFC4279RFC4279RFC4279RFC4162RFC4162RFC4162RFC4162RFC4162RFC4162RFC5288RFC5288RFC5288RFC5288RFC5288RFC5288RFC5288RFC5288RFC5288RFC5288RFC5288RFC5288RFC5487RFC5487RFC5487RFC5487RFC5487RFC5487RFC5487RFC5487RFC5487 RFC-ietf-tls-rfc8447bis-14RFC5487 RFC-ietf-tls-rfc8447bis-14RFC5487RFC5487RFC5487RFC5487RFC5487RFC5487RFC5487RFC5487RFC5932RFC5932RFC5932RFC5932RFC5932RFC5932RFC5932RFC5932RFC5932RFC5932RFC5932RFC5932RFC8998RFC8998TLS_EMPTY_RENEGOTIATION_INFO_SCSVRFC-ietf-tls-rfc8446bis-13RFC-ietf-tls-rfc8446bis-13RFC-ietf-tls-rfc8446bis-13RFC-ietf-tls-rfc8446bis-13RFC-ietf-tls-rfc8446bis-13 IESG Action 2018-08-16draft-irtf-cfrg-aegis-aead-08]TLS_AEGIS_128L_SHA256TLS_FALLBACK_SCSVRFC8422RFC8422 RFC6347RFC8422RFC8422RFC8422RFC8422 RFC-ietf-tls-rfc8447bis-14RFC8422 RFC6347 RFC-ietf-tls-rfc8447bis-14RFC8422RFC8422RFC8422RFC8422RFC8422 RFC6347RFC8422RFC8422RFC8422RFC8422 RFC-ietf-tls-rfc8447bis-14RFC8422 RFC6347 RFC-ietf-tls-rfc8447bis-14RFC8422RFC8422RFC8422RFC8422RFC8422 RFC6347RFC8422RFC8422RFC8422RFC5054RFC5054RFC5054RFC5054RFC5054RFC5054RFC5054RFC5054RFC5054RFC5289RFC5289RFC5289RFC5289RFC5289RFC5289RFC5289RFC5289RFC5289RFC5289RFC5289RFC5289RFC5289RFC5289RFC5289RFC5289RFC5489 RFC6347 RFC-ietf-tls-rfc8447bis-14RFC5489RFC5489RFC5489RFC5489RFC5489RFC5489 RFC-ietf-tls-rfc8447bis-14RFC5489 RFC-ietf-tls-rfc8447bis-14RFC5489 RFC-ietf-tls-rfc8447bis-14RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6209RFC6367RFC6367RFC6367RFC6367RFC6367RFC6367RFC6367RFC6367RFC6367RFC6367RFC6367RFC6367RFC6367RFC6367RFC6367RFC6367RFC6367RFC6367RFC6367RFC6367RFC6367RFC6367RFC6367RFC6367RFC6367RFC6367RFC6367RFC6367RFC6367RFC6367RFC6367RFC6367RFC6367RFC6367RFC6367RFC6367RFC6367RFC6367RFC6367RFC6367RFC6367RFC6367RFC6655RFC6655RFC6655RFC6655RFC6655RFC6655RFC6655RFC6655RFC6655RFC6655RFC6655RFC6655RFC6655RFC6655RFC6655RFC6655RFC7251RFC7251RFC7251RFC7251RFC8492RFC8492RFC8492RFC8492RFC9150 RFC-ietf-tls-rfc8447bis-14RFC9150 RFC-ietf-tls-rfc8447bis-14RFC9189RFC9189RFC9189RFC9367RFC9367RFC9367RFC9367RFC7905RFC7905RFC7905RFC7905RFC7905RFC7905RFC7905RFC8442RFC8442RFC8442TLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256"
|
||||||
|
|
||||||
|
var _TLSCipherSuite_map = map[TLSCipherSuite]string{
|
||||||
|
0: _TLSCipherSuite_name[0:23],
|
||||||
|
1: _TLSCipherSuite_name[23:30],
|
||||||
|
2: _TLSCipherSuite_name[30:37],
|
||||||
|
3: _TLSCipherSuite_name[37:52],
|
||||||
|
4: _TLSCipherSuite_name[52:67],
|
||||||
|
5: _TLSCipherSuite_name[67:82],
|
||||||
|
6: _TLSCipherSuite_name[82:89],
|
||||||
|
7: _TLSCipherSuite_name[89:96],
|
||||||
|
8: _TLSCipherSuite_name[96:103],
|
||||||
|
9: _TLSCipherSuite_name[103:110],
|
||||||
|
10: _TLSCipherSuite_name[110:117],
|
||||||
|
11: _TLSCipherSuite_name[117:124],
|
||||||
|
12: _TLSCipherSuite_name[124:131],
|
||||||
|
13: _TLSCipherSuite_name[131:138],
|
||||||
|
14: _TLSCipherSuite_name[138:145],
|
||||||
|
15: _TLSCipherSuite_name[145:152],
|
||||||
|
16: _TLSCipherSuite_name[152:159],
|
||||||
|
17: _TLSCipherSuite_name[159:166],
|
||||||
|
18: _TLSCipherSuite_name[166:173],
|
||||||
|
19: _TLSCipherSuite_name[173:180],
|
||||||
|
20: _TLSCipherSuite_name[180:187],
|
||||||
|
21: _TLSCipherSuite_name[187:194],
|
||||||
|
22: _TLSCipherSuite_name[194:201],
|
||||||
|
23: _TLSCipherSuite_name[201:216],
|
||||||
|
24: _TLSCipherSuite_name[216:231],
|
||||||
|
25: _TLSCipherSuite_name[231:238],
|
||||||
|
26: _TLSCipherSuite_name[238:245],
|
||||||
|
27: _TLSCipherSuite_name[245:252],
|
||||||
|
30: _TLSCipherSuite_name[252:286],
|
||||||
|
31: _TLSCipherSuite_name[286:293],
|
||||||
|
32: _TLSCipherSuite_name[293:335],
|
||||||
|
33: _TLSCipherSuite_name[335:369],
|
||||||
|
34: _TLSCipherSuite_name[369:403],
|
||||||
|
35: _TLSCipherSuite_name[403:410],
|
||||||
|
36: _TLSCipherSuite_name[410:452],
|
||||||
|
37: _TLSCipherSuite_name[452:486],
|
||||||
|
38: _TLSCipherSuite_name[486:520],
|
||||||
|
39: _TLSCipherSuite_name[520:554],
|
||||||
|
40: _TLSCipherSuite_name[554:596],
|
||||||
|
41: _TLSCipherSuite_name[596:630],
|
||||||
|
42: _TLSCipherSuite_name[630:664],
|
||||||
|
43: _TLSCipherSuite_name[664:706],
|
||||||
|
44: _TLSCipherSuite_name[706:740],
|
||||||
|
45: _TLSCipherSuite_name[740:747],
|
||||||
|
46: _TLSCipherSuite_name[747:754],
|
||||||
|
47: _TLSCipherSuite_name[754:761],
|
||||||
|
48: _TLSCipherSuite_name[761:768],
|
||||||
|
49: _TLSCipherSuite_name[768:775],
|
||||||
|
50: _TLSCipherSuite_name[775:782],
|
||||||
|
51: _TLSCipherSuite_name[782:789],
|
||||||
|
52: _TLSCipherSuite_name[789:796],
|
||||||
|
53: _TLSCipherSuite_name[796:803],
|
||||||
|
54: _TLSCipherSuite_name[803:810],
|
||||||
|
55: _TLSCipherSuite_name[810:817],
|
||||||
|
56: _TLSCipherSuite_name[817:824],
|
||||||
|
57: _TLSCipherSuite_name[824:831],
|
||||||
|
58: _TLSCipherSuite_name[831:838],
|
||||||
|
59: _TLSCipherSuite_name[838:845],
|
||||||
|
60: _TLSCipherSuite_name[845:852],
|
||||||
|
61: _TLSCipherSuite_name[852:859],
|
||||||
|
62: _TLSCipherSuite_name[859:866],
|
||||||
|
63: _TLSCipherSuite_name[866:873],
|
||||||
|
64: _TLSCipherSuite_name[873:880],
|
||||||
|
65: _TLSCipherSuite_name[880:887],
|
||||||
|
66: _TLSCipherSuite_name[887:894],
|
||||||
|
67: _TLSCipherSuite_name[894:901],
|
||||||
|
68: _TLSCipherSuite_name[901:908],
|
||||||
|
69: _TLSCipherSuite_name[908:915],
|
||||||
|
70: _TLSCipherSuite_name[915:922],
|
||||||
|
103: _TLSCipherSuite_name[922:929],
|
||||||
|
104: _TLSCipherSuite_name[929:936],
|
||||||
|
105: _TLSCipherSuite_name[936:943],
|
||||||
|
106: _TLSCipherSuite_name[943:950],
|
||||||
|
107: _TLSCipherSuite_name[950:957],
|
||||||
|
108: _TLSCipherSuite_name[957:964],
|
||||||
|
109: _TLSCipherSuite_name[964:971],
|
||||||
|
132: _TLSCipherSuite_name[971:978],
|
||||||
|
133: _TLSCipherSuite_name[978:985],
|
||||||
|
134: _TLSCipherSuite_name[985:992],
|
||||||
|
135: _TLSCipherSuite_name[992:999],
|
||||||
|
136: _TLSCipherSuite_name[999:1006],
|
||||||
|
137: _TLSCipherSuite_name[1006:1013],
|
||||||
|
138: _TLSCipherSuite_name[1013:1055],
|
||||||
|
139: _TLSCipherSuite_name[1055:1062],
|
||||||
|
140: _TLSCipherSuite_name[1062:1069],
|
||||||
|
141: _TLSCipherSuite_name[1069:1076],
|
||||||
|
142: _TLSCipherSuite_name[1076:1091],
|
||||||
|
143: _TLSCipherSuite_name[1091:1098],
|
||||||
|
144: _TLSCipherSuite_name[1098:1105],
|
||||||
|
145: _TLSCipherSuite_name[1105:1112],
|
||||||
|
146: _TLSCipherSuite_name[1112:1127],
|
||||||
|
147: _TLSCipherSuite_name[1127:1134],
|
||||||
|
148: _TLSCipherSuite_name[1134:1141],
|
||||||
|
149: _TLSCipherSuite_name[1141:1148],
|
||||||
|
150: _TLSCipherSuite_name[1148:1155],
|
||||||
|
151: _TLSCipherSuite_name[1155:1162],
|
||||||
|
152: _TLSCipherSuite_name[1162:1169],
|
||||||
|
153: _TLSCipherSuite_name[1169:1176],
|
||||||
|
154: _TLSCipherSuite_name[1176:1183],
|
||||||
|
155: _TLSCipherSuite_name[1183:1190],
|
||||||
|
156: _TLSCipherSuite_name[1190:1197],
|
||||||
|
157: _TLSCipherSuite_name[1197:1204],
|
||||||
|
158: _TLSCipherSuite_name[1204:1211],
|
||||||
|
159: _TLSCipherSuite_name[1211:1218],
|
||||||
|
160: _TLSCipherSuite_name[1218:1225],
|
||||||
|
161: _TLSCipherSuite_name[1225:1232],
|
||||||
|
162: _TLSCipherSuite_name[1232:1239],
|
||||||
|
163: _TLSCipherSuite_name[1239:1246],
|
||||||
|
164: _TLSCipherSuite_name[1246:1253],
|
||||||
|
165: _TLSCipherSuite_name[1253:1260],
|
||||||
|
166: _TLSCipherSuite_name[1260:1267],
|
||||||
|
167: _TLSCipherSuite_name[1267:1274],
|
||||||
|
168: _TLSCipherSuite_name[1274:1281],
|
||||||
|
169: _TLSCipherSuite_name[1281:1288],
|
||||||
|
170: _TLSCipherSuite_name[1288:1295],
|
||||||
|
171: _TLSCipherSuite_name[1295:1302],
|
||||||
|
172: _TLSCipherSuite_name[1302:1309],
|
||||||
|
173: _TLSCipherSuite_name[1309:1316],
|
||||||
|
174: _TLSCipherSuite_name[1316:1323],
|
||||||
|
175: _TLSCipherSuite_name[1323:1330],
|
||||||
|
176: _TLSCipherSuite_name[1330:1364],
|
||||||
|
177: _TLSCipherSuite_name[1364:1398],
|
||||||
|
178: _TLSCipherSuite_name[1398:1405],
|
||||||
|
179: _TLSCipherSuite_name[1405:1412],
|
||||||
|
180: _TLSCipherSuite_name[1412:1419],
|
||||||
|
181: _TLSCipherSuite_name[1419:1426],
|
||||||
|
182: _TLSCipherSuite_name[1426:1433],
|
||||||
|
183: _TLSCipherSuite_name[1433:1440],
|
||||||
|
184: _TLSCipherSuite_name[1440:1447],
|
||||||
|
185: _TLSCipherSuite_name[1447:1454],
|
||||||
|
186: _TLSCipherSuite_name[1454:1461],
|
||||||
|
187: _TLSCipherSuite_name[1461:1468],
|
||||||
|
188: _TLSCipherSuite_name[1468:1475],
|
||||||
|
189: _TLSCipherSuite_name[1475:1482],
|
||||||
|
190: _TLSCipherSuite_name[1482:1489],
|
||||||
|
191: _TLSCipherSuite_name[1489:1496],
|
||||||
|
192: _TLSCipherSuite_name[1496:1503],
|
||||||
|
193: _TLSCipherSuite_name[1503:1510],
|
||||||
|
194: _TLSCipherSuite_name[1510:1517],
|
||||||
|
195: _TLSCipherSuite_name[1517:1524],
|
||||||
|
196: _TLSCipherSuite_name[1524:1531],
|
||||||
|
197: _TLSCipherSuite_name[1531:1538],
|
||||||
|
198: _TLSCipherSuite_name[1538:1545],
|
||||||
|
199: _TLSCipherSuite_name[1545:1552],
|
||||||
|
255: _TLSCipherSuite_name[1552:1585],
|
||||||
|
4865: _TLSCipherSuite_name[1585:1611],
|
||||||
|
4866: _TLSCipherSuite_name[1611:1637],
|
||||||
|
4867: _TLSCipherSuite_name[1637:1663],
|
||||||
|
4868: _TLSCipherSuite_name[1663:1689],
|
||||||
|
4869: _TLSCipherSuite_name[1689:1738],
|
||||||
|
4870: _TLSCipherSuite_name[1738:1768],
|
||||||
|
4871: _TLSCipherSuite_name[1768:1789],
|
||||||
|
22016: _TLSCipherSuite_name[1789:1806],
|
||||||
|
49153: _TLSCipherSuite_name[1806:1813],
|
||||||
|
49154: _TLSCipherSuite_name[1813:1828],
|
||||||
|
49155: _TLSCipherSuite_name[1828:1835],
|
||||||
|
49156: _TLSCipherSuite_name[1835:1842],
|
||||||
|
49157: _TLSCipherSuite_name[1842:1849],
|
||||||
|
49158: _TLSCipherSuite_name[1849:1883],
|
||||||
|
49159: _TLSCipherSuite_name[1883:1925],
|
||||||
|
49160: _TLSCipherSuite_name[1925:1932],
|
||||||
|
49161: _TLSCipherSuite_name[1932:1939],
|
||||||
|
49162: _TLSCipherSuite_name[1939:1946],
|
||||||
|
49163: _TLSCipherSuite_name[1946:1953],
|
||||||
|
49164: _TLSCipherSuite_name[1953:1968],
|
||||||
|
49165: _TLSCipherSuite_name[1968:1975],
|
||||||
|
49166: _TLSCipherSuite_name[1975:1982],
|
||||||
|
49167: _TLSCipherSuite_name[1982:1989],
|
||||||
|
49168: _TLSCipherSuite_name[1989:2023],
|
||||||
|
49169: _TLSCipherSuite_name[2023:2065],
|
||||||
|
49170: _TLSCipherSuite_name[2065:2072],
|
||||||
|
49171: _TLSCipherSuite_name[2072:2079],
|
||||||
|
49172: _TLSCipherSuite_name[2079:2086],
|
||||||
|
49173: _TLSCipherSuite_name[2086:2093],
|
||||||
|
49174: _TLSCipherSuite_name[2093:2108],
|
||||||
|
49175: _TLSCipherSuite_name[2108:2115],
|
||||||
|
49176: _TLSCipherSuite_name[2115:2122],
|
||||||
|
49177: _TLSCipherSuite_name[2122:2129],
|
||||||
|
49178: _TLSCipherSuite_name[2129:2136],
|
||||||
|
49179: _TLSCipherSuite_name[2136:2143],
|
||||||
|
49180: _TLSCipherSuite_name[2143:2150],
|
||||||
|
49181: _TLSCipherSuite_name[2150:2157],
|
||||||
|
49182: _TLSCipherSuite_name[2157:2164],
|
||||||
|
49183: _TLSCipherSuite_name[2164:2171],
|
||||||
|
49184: _TLSCipherSuite_name[2171:2178],
|
||||||
|
49185: _TLSCipherSuite_name[2178:2185],
|
||||||
|
49186: _TLSCipherSuite_name[2185:2192],
|
||||||
|
49187: _TLSCipherSuite_name[2192:2199],
|
||||||
|
49188: _TLSCipherSuite_name[2199:2206],
|
||||||
|
49189: _TLSCipherSuite_name[2206:2213],
|
||||||
|
49190: _TLSCipherSuite_name[2213:2220],
|
||||||
|
49191: _TLSCipherSuite_name[2220:2227],
|
||||||
|
49192: _TLSCipherSuite_name[2227:2234],
|
||||||
|
49193: _TLSCipherSuite_name[2234:2241],
|
||||||
|
49194: _TLSCipherSuite_name[2241:2248],
|
||||||
|
49195: _TLSCipherSuite_name[2248:2255],
|
||||||
|
49196: _TLSCipherSuite_name[2255:2262],
|
||||||
|
49197: _TLSCipherSuite_name[2262:2269],
|
||||||
|
49198: _TLSCipherSuite_name[2269:2276],
|
||||||
|
49199: _TLSCipherSuite_name[2276:2283],
|
||||||
|
49200: _TLSCipherSuite_name[2283:2290],
|
||||||
|
49201: _TLSCipherSuite_name[2290:2297],
|
||||||
|
49202: _TLSCipherSuite_name[2297:2304],
|
||||||
|
49203: _TLSCipherSuite_name[2304:2346],
|
||||||
|
49204: _TLSCipherSuite_name[2346:2353],
|
||||||
|
49205: _TLSCipherSuite_name[2353:2360],
|
||||||
|
49206: _TLSCipherSuite_name[2360:2367],
|
||||||
|
49207: _TLSCipherSuite_name[2367:2374],
|
||||||
|
49208: _TLSCipherSuite_name[2374:2381],
|
||||||
|
49209: _TLSCipherSuite_name[2381:2415],
|
||||||
|
49210: _TLSCipherSuite_name[2415:2449],
|
||||||
|
49211: _TLSCipherSuite_name[2449:2483],
|
||||||
|
49212: _TLSCipherSuite_name[2483:2490],
|
||||||
|
49213: _TLSCipherSuite_name[2490:2497],
|
||||||
|
49214: _TLSCipherSuite_name[2497:2504],
|
||||||
|
49215: _TLSCipherSuite_name[2504:2511],
|
||||||
|
49216: _TLSCipherSuite_name[2511:2518],
|
||||||
|
49217: _TLSCipherSuite_name[2518:2525],
|
||||||
|
49218: _TLSCipherSuite_name[2525:2532],
|
||||||
|
49219: _TLSCipherSuite_name[2532:2539],
|
||||||
|
49220: _TLSCipherSuite_name[2539:2546],
|
||||||
|
49221: _TLSCipherSuite_name[2546:2553],
|
||||||
|
49222: _TLSCipherSuite_name[2553:2560],
|
||||||
|
49223: _TLSCipherSuite_name[2560:2567],
|
||||||
|
49224: _TLSCipherSuite_name[2567:2574],
|
||||||
|
49225: _TLSCipherSuite_name[2574:2581],
|
||||||
|
49226: _TLSCipherSuite_name[2581:2588],
|
||||||
|
49227: _TLSCipherSuite_name[2588:2595],
|
||||||
|
49228: _TLSCipherSuite_name[2595:2602],
|
||||||
|
49229: _TLSCipherSuite_name[2602:2609],
|
||||||
|
49230: _TLSCipherSuite_name[2609:2616],
|
||||||
|
49231: _TLSCipherSuite_name[2616:2623],
|
||||||
|
49232: _TLSCipherSuite_name[2623:2630],
|
||||||
|
49233: _TLSCipherSuite_name[2630:2637],
|
||||||
|
49234: _TLSCipherSuite_name[2637:2644],
|
||||||
|
49235: _TLSCipherSuite_name[2644:2651],
|
||||||
|
49236: _TLSCipherSuite_name[2651:2658],
|
||||||
|
49237: _TLSCipherSuite_name[2658:2665],
|
||||||
|
49238: _TLSCipherSuite_name[2665:2672],
|
||||||
|
49239: _TLSCipherSuite_name[2672:2679],
|
||||||
|
49240: _TLSCipherSuite_name[2679:2686],
|
||||||
|
49241: _TLSCipherSuite_name[2686:2693],
|
||||||
|
49242: _TLSCipherSuite_name[2693:2700],
|
||||||
|
49243: _TLSCipherSuite_name[2700:2707],
|
||||||
|
49244: _TLSCipherSuite_name[2707:2714],
|
||||||
|
49245: _TLSCipherSuite_name[2714:2721],
|
||||||
|
49246: _TLSCipherSuite_name[2721:2728],
|
||||||
|
49247: _TLSCipherSuite_name[2728:2735],
|
||||||
|
49248: _TLSCipherSuite_name[2735:2742],
|
||||||
|
49249: _TLSCipherSuite_name[2742:2749],
|
||||||
|
49250: _TLSCipherSuite_name[2749:2756],
|
||||||
|
49251: _TLSCipherSuite_name[2756:2763],
|
||||||
|
49252: _TLSCipherSuite_name[2763:2770],
|
||||||
|
49253: _TLSCipherSuite_name[2770:2777],
|
||||||
|
49254: _TLSCipherSuite_name[2777:2784],
|
||||||
|
49255: _TLSCipherSuite_name[2784:2791],
|
||||||
|
49256: _TLSCipherSuite_name[2791:2798],
|
||||||
|
49257: _TLSCipherSuite_name[2798:2805],
|
||||||
|
49258: _TLSCipherSuite_name[2805:2812],
|
||||||
|
49259: _TLSCipherSuite_name[2812:2819],
|
||||||
|
49260: _TLSCipherSuite_name[2819:2826],
|
||||||
|
49261: _TLSCipherSuite_name[2826:2833],
|
||||||
|
49262: _TLSCipherSuite_name[2833:2840],
|
||||||
|
49263: _TLSCipherSuite_name[2840:2847],
|
||||||
|
49264: _TLSCipherSuite_name[2847:2854],
|
||||||
|
49265: _TLSCipherSuite_name[2854:2861],
|
||||||
|
49266: _TLSCipherSuite_name[2861:2868],
|
||||||
|
49267: _TLSCipherSuite_name[2868:2875],
|
||||||
|
49268: _TLSCipherSuite_name[2875:2882],
|
||||||
|
49269: _TLSCipherSuite_name[2882:2889],
|
||||||
|
49270: _TLSCipherSuite_name[2889:2896],
|
||||||
|
49271: _TLSCipherSuite_name[2896:2903],
|
||||||
|
49272: _TLSCipherSuite_name[2903:2910],
|
||||||
|
49273: _TLSCipherSuite_name[2910:2917],
|
||||||
|
49274: _TLSCipherSuite_name[2917:2924],
|
||||||
|
49275: _TLSCipherSuite_name[2924:2931],
|
||||||
|
49276: _TLSCipherSuite_name[2931:2938],
|
||||||
|
49277: _TLSCipherSuite_name[2938:2945],
|
||||||
|
49278: _TLSCipherSuite_name[2945:2952],
|
||||||
|
49279: _TLSCipherSuite_name[2952:2959],
|
||||||
|
49280: _TLSCipherSuite_name[2959:2966],
|
||||||
|
49281: _TLSCipherSuite_name[2966:2973],
|
||||||
|
49282: _TLSCipherSuite_name[2973:2980],
|
||||||
|
49283: _TLSCipherSuite_name[2980:2987],
|
||||||
|
49284: _TLSCipherSuite_name[2987:2994],
|
||||||
|
49285: _TLSCipherSuite_name[2994:3001],
|
||||||
|
49286: _TLSCipherSuite_name[3001:3008],
|
||||||
|
49287: _TLSCipherSuite_name[3008:3015],
|
||||||
|
49288: _TLSCipherSuite_name[3015:3022],
|
||||||
|
49289: _TLSCipherSuite_name[3022:3029],
|
||||||
|
49290: _TLSCipherSuite_name[3029:3036],
|
||||||
|
49291: _TLSCipherSuite_name[3036:3043],
|
||||||
|
49292: _TLSCipherSuite_name[3043:3050],
|
||||||
|
49293: _TLSCipherSuite_name[3050:3057],
|
||||||
|
49294: _TLSCipherSuite_name[3057:3064],
|
||||||
|
49295: _TLSCipherSuite_name[3064:3071],
|
||||||
|
49296: _TLSCipherSuite_name[3071:3078],
|
||||||
|
49297: _TLSCipherSuite_name[3078:3085],
|
||||||
|
49298: _TLSCipherSuite_name[3085:3092],
|
||||||
|
49299: _TLSCipherSuite_name[3092:3099],
|
||||||
|
49300: _TLSCipherSuite_name[3099:3106],
|
||||||
|
49301: _TLSCipherSuite_name[3106:3113],
|
||||||
|
49302: _TLSCipherSuite_name[3113:3120],
|
||||||
|
49303: _TLSCipherSuite_name[3120:3127],
|
||||||
|
49304: _TLSCipherSuite_name[3127:3134],
|
||||||
|
49305: _TLSCipherSuite_name[3134:3141],
|
||||||
|
49306: _TLSCipherSuite_name[3141:3148],
|
||||||
|
49307: _TLSCipherSuite_name[3148:3155],
|
||||||
|
49308: _TLSCipherSuite_name[3155:3162],
|
||||||
|
49309: _TLSCipherSuite_name[3162:3169],
|
||||||
|
49310: _TLSCipherSuite_name[3169:3176],
|
||||||
|
49311: _TLSCipherSuite_name[3176:3183],
|
||||||
|
49312: _TLSCipherSuite_name[3183:3190],
|
||||||
|
49313: _TLSCipherSuite_name[3190:3197],
|
||||||
|
49314: _TLSCipherSuite_name[3197:3204],
|
||||||
|
49315: _TLSCipherSuite_name[3204:3211],
|
||||||
|
49316: _TLSCipherSuite_name[3211:3218],
|
||||||
|
49317: _TLSCipherSuite_name[3218:3225],
|
||||||
|
49318: _TLSCipherSuite_name[3225:3232],
|
||||||
|
49319: _TLSCipherSuite_name[3232:3239],
|
||||||
|
49320: _TLSCipherSuite_name[3239:3246],
|
||||||
|
49321: _TLSCipherSuite_name[3246:3253],
|
||||||
|
49322: _TLSCipherSuite_name[3253:3260],
|
||||||
|
49323: _TLSCipherSuite_name[3260:3267],
|
||||||
|
49324: _TLSCipherSuite_name[3267:3274],
|
||||||
|
49325: _TLSCipherSuite_name[3274:3281],
|
||||||
|
49326: _TLSCipherSuite_name[3281:3288],
|
||||||
|
49327: _TLSCipherSuite_name[3288:3295],
|
||||||
|
49328: _TLSCipherSuite_name[3295:3302],
|
||||||
|
49329: _TLSCipherSuite_name[3302:3309],
|
||||||
|
49330: _TLSCipherSuite_name[3309:3316],
|
||||||
|
49331: _TLSCipherSuite_name[3316:3323],
|
||||||
|
49332: _TLSCipherSuite_name[3323:3357],
|
||||||
|
49333: _TLSCipherSuite_name[3357:3391],
|
||||||
|
49408: _TLSCipherSuite_name[3391:3398],
|
||||||
|
49409: _TLSCipherSuite_name[3398:3405],
|
||||||
|
49410: _TLSCipherSuite_name[3405:3412],
|
||||||
|
49411: _TLSCipherSuite_name[3412:3419],
|
||||||
|
49412: _TLSCipherSuite_name[3419:3426],
|
||||||
|
49413: _TLSCipherSuite_name[3426:3433],
|
||||||
|
49414: _TLSCipherSuite_name[3433:3440],
|
||||||
|
52392: _TLSCipherSuite_name[3440:3447],
|
||||||
|
52393: _TLSCipherSuite_name[3447:3454],
|
||||||
|
52394: _TLSCipherSuite_name[3454:3461],
|
||||||
|
52395: _TLSCipherSuite_name[3461:3468],
|
||||||
|
52396: _TLSCipherSuite_name[3468:3475],
|
||||||
|
52397: _TLSCipherSuite_name[3475:3482],
|
||||||
|
52398: _TLSCipherSuite_name[3482:3489],
|
||||||
|
53249: _TLSCipherSuite_name[3489:3496],
|
||||||
|
53250: _TLSCipherSuite_name[3496:3503],
|
||||||
|
53251: _TLSCipherSuite_name[3503:3510],
|
||||||
|
53253: _TLSCipherSuite_name[3510:3547],
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i TLSCipherSuite) String() string {
|
||||||
|
if str, ok := _TLSCipherSuite_map[i]; ok {
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
return "TLSCipherSuite(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||||
|
}
|
||||||
|
func _() {
|
||||||
|
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||||
|
// Re-run the stringer command to generate them again.
|
||||||
|
var x [1]struct{}
|
||||||
|
_ = x[PKCS1WithSHA256-1025]
|
||||||
|
_ = x[PKCS1WithSHA384-1281]
|
||||||
|
_ = x[PKCS1WithSHA512-1537]
|
||||||
|
_ = x[PSSWithSHA256-2052]
|
||||||
|
_ = x[PSSWithSHA384-2053]
|
||||||
|
_ = x[PSSWithSHA512-2054]
|
||||||
|
_ = x[ECDSAWithP256AndSHA256-1027]
|
||||||
|
_ = x[ECDSAWithP384AndSHA384-1283]
|
||||||
|
_ = x[ECDSAWithP521AndSHA512-1539]
|
||||||
|
_ = x[Ed25519-2055]
|
||||||
|
_ = x[PKCS1WithSHA1-513]
|
||||||
|
_ = x[ECDSAWithSHA1-515]
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
_TLSSignatureScheme_name_0 = "PKCS1WithSHA1"
|
||||||
|
_TLSSignatureScheme_name_1 = "ECDSAWithSHA1"
|
||||||
|
_TLSSignatureScheme_name_2 = "PKCS1WithSHA256"
|
||||||
|
_TLSSignatureScheme_name_3 = "ECDSAWithP256AndSHA256"
|
||||||
|
_TLSSignatureScheme_name_4 = "PKCS1WithSHA384"
|
||||||
|
_TLSSignatureScheme_name_5 = "ECDSAWithP384AndSHA384"
|
||||||
|
_TLSSignatureScheme_name_6 = "PKCS1WithSHA512"
|
||||||
|
_TLSSignatureScheme_name_7 = "ECDSAWithP521AndSHA512"
|
||||||
|
_TLSSignatureScheme_name_8 = "PSSWithSHA256PSSWithSHA384PSSWithSHA512Ed25519"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
_TLSSignatureScheme_index_8 = [...]uint8{0, 13, 26, 39, 46}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (i TLSSignatureScheme) String() string {
|
||||||
|
switch {
|
||||||
|
case i == 513:
|
||||||
|
return _TLSSignatureScheme_name_0
|
||||||
|
case i == 515:
|
||||||
|
return _TLSSignatureScheme_name_1
|
||||||
|
case i == 1025:
|
||||||
|
return _TLSSignatureScheme_name_2
|
||||||
|
case i == 1027:
|
||||||
|
return _TLSSignatureScheme_name_3
|
||||||
|
case i == 1281:
|
||||||
|
return _TLSSignatureScheme_name_4
|
||||||
|
case i == 1283:
|
||||||
|
return _TLSSignatureScheme_name_5
|
||||||
|
case i == 1537:
|
||||||
|
return _TLSSignatureScheme_name_6
|
||||||
|
case i == 1539:
|
||||||
|
return _TLSSignatureScheme_name_7
|
||||||
|
case 2052 <= i && i <= 2055:
|
||||||
|
i -= 2052
|
||||||
|
return _TLSSignatureScheme_name_8[_TLSSignatureScheme_index_8[i]:_TLSSignatureScheme_index_8[i+1]]
|
||||||
|
default:
|
||||||
|
return "TLSSignatureScheme(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||||
|
}
|
||||||
|
}
|
91
tls_test.go
Normal file
91
tls_test.go
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
package dpi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/hex"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestDecodeTLSClientHello(t *testing.T) {
|
||||||
|
// Taken from a random PCAP on the internet
|
||||||
|
clientHelloBytes, err := testDecodeHexString(`
|
||||||
|
1603 0100 c801 0000 c403 03ec 12dd
|
||||||
|
1764 a439 fd7e 8c85 46b8 4d1e a06e b3d7
|
||||||
|
a051 f03c b817 470d 4c54 c5df 7200 001c
|
||||||
|
eaea c02b c02f c02c c030 cca9 cca8 c013
|
||||||
|
c014 009c 009d 002f 0035 000a 0100 007f
|
||||||
|
dada 0000 ff01 0001 0000 0000 1600 1400
|
||||||
|
0011 7777 772e 7769 6b69 7065 6469 612e
|
||||||
|
6f72 6700 1700 0000 2300 0000 0d00 1400
|
||||||
|
1204 0308 0404 0105 0308 0505 0108 0606
|
||||||
|
0102 0100 0500 0501 0000 0000 0012 0000
|
||||||
|
0010 000e 000c 0268 3208 6874 7470 2f31
|
||||||
|
2e31 7550 0000 000b 0002 0100 000a 000a
|
||||||
|
0008 1a1a 001d 0017 0018 1a1a 0001 00
|
||||||
|
`)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to decode test ClientHello: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Taken from RFC8443 TLS 1.3 traces example:
|
||||||
|
rfc8443ClientHelloBytes, err := testDecodeHexString(`
|
||||||
|
16 03 01 00 c4 01 00 00 c0 03 03 cb
|
||||||
|
34 ec b1 e7 81 63 ba 1c 38 c6 da cb 19 6a 6d ff a2 1a 8d 99 12
|
||||||
|
ec 18 a2 ef 62 83 02 4d ec e7 00 00 06 13 01 13 03 13 02 01 00
|
||||||
|
00 91 00 00 00 0b 00 09 00 00 06 73 65 72 76 65 72 ff 01 00 01
|
||||||
|
00 00 0a 00 14 00 12 00 1d 00 17 00 18 00 19 01 00 01 01 01 02
|
||||||
|
01 03 01 04 00 23 00 00 00 33 00 26 00 24 00 1d 00 20 99 38 1d
|
||||||
|
e5 60 e4 bd 43 d2 3d 8e 43 5a 7d ba fe b3 c0 6e 51 c1 3c ae 4d
|
||||||
|
54 13 69 1e 52 9a af 2c 00 2b 00 03 02 03 04 00 0d 00 20 00 1e
|
||||||
|
04 03 05 03 06 03 02 03 08 04 08 05 08 06 04 01 05 01 06 01 02
|
||||||
|
01 04 02 05 02 06 02 02 02 00 2d 00 02 01 01 00 1c 00 02 40 01
|
||||||
|
`)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to decode test ClientHello: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("Client Hello", func(t *testing.T) {
|
||||||
|
hello, err := DecodeTLSClientHelloHandshake(clientHelloBytes)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
hello.Raw = nil
|
||||||
|
t.Logf("%#v", hello)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("TLS 1.3 Client Hello", func(t *testing.T) {
|
||||||
|
hello, err := DecodeTLSClientHelloHandshake(rfc8443ClientHelloBytes)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
hello.Raw = nil
|
||||||
|
t.Logf("%#v", hello)
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDecodeTLSServerHello(t *testing.T) {
|
||||||
|
serverHelloBytes, err := hex.DecodeString("02000030030300000000000000000000000000000000000000000000000000000000000000000000000000080005000000050000")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to decode test ServerHello: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("Server Hello", func(t *testing.T) {
|
||||||
|
hello, err := DecodeTLSServerHello(serverHelloBytes)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t.Logf("%#+v", hello)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func testDecodeHexString(s string) ([]byte, error) {
|
||||||
|
s = strings.TrimSpace(s)
|
||||||
|
s = strings.ReplaceAll(s, " ", "")
|
||||||
|
s = strings.ReplaceAll(s, "\n", "")
|
||||||
|
s = strings.ReplaceAll(s, "\t", "")
|
||||||
|
return hex.DecodeString(s)
|
||||||
|
}
|
Reference in New Issue
Block a user