| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241 |
- // 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"
- }
|