Import cloudflare tls
This commit is contained in:
241
transport/cloudflaretls/tls_cf.go
Normal file
241
transport/cloudflaretls/tls_cf.go
Normal file
@@ -0,0 +1,241 @@
|
||||
// Copyright 2021 Cloudflare, Inc. All rights reserved. Use of this source code
|
||||
// is governed by a BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
package tls
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
circlPki "github.com/cloudflare/circl/pki"
|
||||
circlSign "github.com/cloudflare/circl/sign"
|
||||
"github.com/cloudflare/circl/sign/eddilithium3"
|
||||
)
|
||||
|
||||
const (
|
||||
// Constants for ECH status events.
|
||||
echStatusBypassed = 1 + iota
|
||||
echStatusInner
|
||||
echStatusOuter
|
||||
)
|
||||
|
||||
// To add a signature scheme from Circl
|
||||
//
|
||||
// 1. make sure it implements TLSScheme and CertificateScheme,
|
||||
// 2. follow the instructions in crypto/x509/x509_cf.go
|
||||
// 3. add a signature<NameOfAlg> to the iota in common.go
|
||||
// 4. add row in the circlSchemes lists below
|
||||
|
||||
var circlSchemes = [...]struct {
|
||||
sigType uint8
|
||||
scheme circlSign.Scheme
|
||||
}{
|
||||
{signatureEdDilithium3, eddilithium3.Scheme()},
|
||||
}
|
||||
|
||||
func circlSchemeBySigType(sigType uint8) circlSign.Scheme {
|
||||
for _, cs := range circlSchemes {
|
||||
if cs.sigType == sigType {
|
||||
return cs.scheme
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func sigTypeByCirclScheme(scheme circlSign.Scheme) uint8 {
|
||||
for _, cs := range circlSchemes {
|
||||
if cs.scheme == scheme {
|
||||
return cs.sigType
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
var supportedSignatureAlgorithmsWithCircl []SignatureScheme
|
||||
|
||||
// supportedSignatureAlgorithms returns enabled signature schemes. PQ signature
|
||||
// schemes are only included when tls.Config#PQSignatureSchemesEnabled is set.
|
||||
func (c *Config) supportedSignatureAlgorithms() []SignatureScheme {
|
||||
if c != nil && c.PQSignatureSchemesEnabled {
|
||||
return supportedSignatureAlgorithmsWithCircl
|
||||
}
|
||||
return supportedSignatureAlgorithms
|
||||
}
|
||||
|
||||
func init() {
|
||||
supportedSignatureAlgorithmsWithCircl = append([]SignatureScheme{}, supportedSignatureAlgorithms...)
|
||||
for _, cs := range circlSchemes {
|
||||
supportedSignatureAlgorithmsWithCircl = append(supportedSignatureAlgorithmsWithCircl,
|
||||
SignatureScheme(cs.scheme.(circlPki.TLSScheme).TLSIdentifier()))
|
||||
}
|
||||
}
|
||||
|
||||
// CFEvent is a value emitted at various points in the handshake that is
|
||||
// handled by the callback Config.CFEventHandler.
|
||||
type CFEvent interface {
|
||||
Name() string
|
||||
}
|
||||
|
||||
// CFEventTLS13ClientHandshakeTimingInfo carries intra-stack time durations for
|
||||
// TLS 1.3 client-state machine changes. It can be used for tracking metrics
|
||||
// during a connection. Some durations may be sensitive, such as the amount of
|
||||
// time to process a particular handshake message, so this event should only be
|
||||
// used for experimental purposes.
|
||||
type CFEventTLS13ClientHandshakeTimingInfo struct {
|
||||
timer func() time.Time
|
||||
start time.Time
|
||||
WriteClientHello time.Duration
|
||||
ProcessServerHello time.Duration
|
||||
ReadEncryptedExtensions time.Duration
|
||||
ReadCertificate time.Duration
|
||||
ReadCertificateVerify time.Duration
|
||||
ReadServerFinished time.Duration
|
||||
WriteCertificate time.Duration
|
||||
WriteCertificateVerify time.Duration
|
||||
WriteClientFinished time.Duration
|
||||
}
|
||||
|
||||
// Name is required by the CFEvent interface.
|
||||
func (e CFEventTLS13ClientHandshakeTimingInfo) Name() string {
|
||||
return "TLS13ClientHandshakeTimingInfo"
|
||||
}
|
||||
|
||||
func (e CFEventTLS13ClientHandshakeTimingInfo) elapsedTime() time.Duration {
|
||||
if e.timer == nil {
|
||||
return 0
|
||||
}
|
||||
return e.timer().Sub(e.start)
|
||||
}
|
||||
|
||||
func createTLS13ClientHandshakeTimingInfo(timerFunc func() time.Time) CFEventTLS13ClientHandshakeTimingInfo {
|
||||
timer := time.Now
|
||||
if timerFunc != nil {
|
||||
timer = timerFunc
|
||||
}
|
||||
|
||||
return CFEventTLS13ClientHandshakeTimingInfo{
|
||||
timer: timer,
|
||||
start: timer(),
|
||||
}
|
||||
}
|
||||
|
||||
// CFEventTLS13ServerHandshakeTimingInfo carries intra-stack time durations
|
||||
// for TLS 1.3 state machine changes. It can be used for tracking metrics during a
|
||||
// connection. Some durations may be sensitive, such as the amount of time to
|
||||
// process a particular handshake message, so this event should only be used
|
||||
// for experimental purposes.
|
||||
type CFEventTLS13ServerHandshakeTimingInfo struct {
|
||||
timer func() time.Time
|
||||
start time.Time
|
||||
ProcessClientHello time.Duration
|
||||
WriteServerHello time.Duration
|
||||
WriteEncryptedExtensions time.Duration
|
||||
WriteCertificate time.Duration
|
||||
WriteCertificateVerify time.Duration
|
||||
WriteServerFinished time.Duration
|
||||
ReadCertificate time.Duration
|
||||
ReadCertificateVerify time.Duration
|
||||
ReadClientFinished time.Duration
|
||||
}
|
||||
|
||||
// Name is required by the CFEvent interface.
|
||||
func (e CFEventTLS13ServerHandshakeTimingInfo) Name() string {
|
||||
return "TLS13ServerHandshakeTimingInfo"
|
||||
}
|
||||
|
||||
func (e CFEventTLS13ServerHandshakeTimingInfo) elapsedTime() time.Duration {
|
||||
if e.timer == nil {
|
||||
return 0
|
||||
}
|
||||
return e.timer().Sub(e.start)
|
||||
}
|
||||
|
||||
func createTLS13ServerHandshakeTimingInfo(timerFunc func() time.Time) CFEventTLS13ServerHandshakeTimingInfo {
|
||||
timer := time.Now
|
||||
if timerFunc != nil {
|
||||
timer = timerFunc
|
||||
}
|
||||
|
||||
return CFEventTLS13ServerHandshakeTimingInfo{
|
||||
timer: timer,
|
||||
start: timer(),
|
||||
}
|
||||
}
|
||||
|
||||
// CFEventECHClientStatus is emitted once it is known whether the client
|
||||
// bypassed, offered, or greased ECH.
|
||||
type CFEventECHClientStatus int
|
||||
|
||||
// Bypassed returns true if the client bypassed ECH.
|
||||
func (e CFEventECHClientStatus) Bypassed() bool {
|
||||
return e == echStatusBypassed
|
||||
}
|
||||
|
||||
// Offered returns true if the client offered ECH.
|
||||
func (e CFEventECHClientStatus) Offered() bool {
|
||||
return e == echStatusInner
|
||||
}
|
||||
|
||||
// Greased returns true if the client greased ECH.
|
||||
func (e CFEventECHClientStatus) Greased() bool {
|
||||
return e == echStatusOuter
|
||||
}
|
||||
|
||||
// Name is required by the CFEvent interface.
|
||||
func (e CFEventECHClientStatus) Name() string {
|
||||
return "ech client status"
|
||||
}
|
||||
|
||||
// CFEventECHServerStatus is emitted once it is known whether the client
|
||||
// bypassed, offered, or greased ECH.
|
||||
type CFEventECHServerStatus int
|
||||
|
||||
// Bypassed returns true if the client bypassed ECH.
|
||||
func (e CFEventECHServerStatus) Bypassed() bool {
|
||||
return e == echStatusBypassed
|
||||
}
|
||||
|
||||
// Accepted returns true if the client offered ECH.
|
||||
func (e CFEventECHServerStatus) Accepted() bool {
|
||||
return e == echStatusInner
|
||||
}
|
||||
|
||||
// Rejected returns true if the client greased ECH.
|
||||
func (e CFEventECHServerStatus) Rejected() bool {
|
||||
return e == echStatusOuter
|
||||
}
|
||||
|
||||
// Name is required by the CFEvent interface.
|
||||
func (e CFEventECHServerStatus) Name() string {
|
||||
return "ech server status"
|
||||
}
|
||||
|
||||
// CFEventECHPublicNameMismatch is emitted if the outer SNI does not match
|
||||
// match the public name of the ECH configuration. Note that we do not record
|
||||
// the outer SNI in order to avoid collecting this potentially sensitive data.
|
||||
type CFEventECHPublicNameMismatch struct{}
|
||||
|
||||
// Name is required by the CFEvent interface.
|
||||
func (e CFEventECHPublicNameMismatch) Name() string {
|
||||
return "ech public name does not match outer sni"
|
||||
}
|
||||
|
||||
// For backwards compatibility.
|
||||
type CFEventTLS13NegotiatedKEX = CFEventTLSNegotiatedNamedKEX
|
||||
|
||||
// CFEventTLSNegotiatedNamedKEX is emitted when a key agreement mechanism has been
|
||||
// established that uses a named group. This includes all key agreements
|
||||
// in TLSv1.3, but excludes RSA and DH in TLS 1.2 and earlier.
|
||||
type CFEventTLSNegotiatedNamedKEX struct {
|
||||
KEX CurveID
|
||||
}
|
||||
|
||||
func (e CFEventTLSNegotiatedNamedKEX) Name() string {
|
||||
return "CFEventTLSNegotiatedNamedKEX"
|
||||
}
|
||||
|
||||
// CFEventTLS13HRR is emitted when a HRR is sent or received
|
||||
type CFEventTLS13HRR struct{}
|
||||
|
||||
func (e CFEventTLS13HRR) Name() string {
|
||||
return "CFEventTLS13HRR"
|
||||
}
|
||||
Reference in New Issue
Block a user