فهرست منبع

Update dependencies

世界 3 سال پیش
والد
کامیت
930d177dd0

+ 1 - 1
common/tls/ech_client.go

@@ -11,9 +11,9 @@ import (
 	"net/netip"
 	"os"
 
+	cftls "github.com/sagernet/cloudflare-tls"
 	"github.com/sagernet/sing-box/adapter"
 	"github.com/sagernet/sing-box/option"
-	cftls "github.com/sagernet/sing-box/transport/cloudflaretls"
 	"github.com/sagernet/sing-dns"
 	E "github.com/sagernet/sing/common/exceptions"
 

+ 10 - 14
go.mod

@@ -6,7 +6,6 @@ require (
 	berty.tech/go-libtor v1.0.385
 	github.com/Dreamacro/clash v1.11.8
 	github.com/caddyserver/certmagic v0.17.2
-	github.com/cloudflare/circl v1.2.1-0.20220831060716-4cf0150356fc
 	github.com/cretz/bine v0.2.0
 	github.com/database64128/tfo-go/v2 v2.0.2
 	github.com/dustin/go-humanize v1.0.0
@@ -22,9 +21,10 @@ require (
 	github.com/oschwald/maxminddb-golang v1.10.0
 	github.com/pires/go-proxyproto v0.6.2
 	github.com/refraction-networking/utls v1.1.5
-	github.com/sagernet/quic-go v0.0.0-20220818150011-de611ab3e2bb
+	github.com/sagernet/cloudflare-tls v0.0.0-20221031050923-d70792f4c3a0
+	github.com/sagernet/quic-go v0.0.0-20221031051350-29d8bb1c8127
 	github.com/sagernet/sing v0.0.0-20221008120626-60a9910eefe4
-	github.com/sagernet/sing-dns v0.0.0-20221029093630-568471e6216d
+	github.com/sagernet/sing-dns v0.0.0-20221031055845-7de76401d403
 	github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6
 	github.com/sagernet/sing-tun v0.0.0-20221028015259-ea5c35f62f07
 	github.com/sagernet/sing-vmess v0.0.0-20220925083655-063bc85ea685
@@ -49,20 +49,17 @@ require (
 require (
 	github.com/ajg/form v1.5.1 // indirect
 	github.com/andybalholm/brotli v1.0.4 // indirect
+	github.com/cloudflare/circl v1.2.1-0.20221019164342-6ab4dfed8f3c // indirect
 	github.com/davecgh/go-spew v1.1.1 // indirect
-	github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect
-	github.com/golang/mock v1.6.0 // indirect
 	github.com/golang/protobuf v1.5.2 // indirect
 	github.com/google/btree v1.0.1 // indirect
 	github.com/inconshreveable/mousetrap v1.0.1 // indirect
 	github.com/klauspost/compress v1.15.9 // indirect
 	github.com/klauspost/cpuid/v2 v2.1.1 // indirect
 	github.com/libdns/libdns v0.2.1 // indirect
-	github.com/marten-seemann/qpack v0.2.1 // indirect
-	github.com/marten-seemann/qtls-go1-18 v0.1.2 // indirect
-	github.com/marten-seemann/qtls-go1-19 v0.1.0 // indirect
-	github.com/nxadm/tail v1.4.8 // indirect
-	github.com/onsi/ginkgo v1.16.5 // indirect
+	github.com/marten-seemann/qpack v0.3.0 // indirect
+	github.com/marten-seemann/qtls-go1-18 v0.1.3 // indirect
+	github.com/marten-seemann/qtls-go1-19 v0.1.1 // indirect
 	github.com/pmezard/go-difflib v1.0.0 // indirect
 	github.com/sagernet/abx-go v0.0.0-20220819185957-dba1257d738e // indirect
 	github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61 // indirect
@@ -71,14 +68,13 @@ require (
 	github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect
 	go.uber.org/multierr v1.6.0 // indirect
 	go.uber.org/zap v1.23.0 // indirect
-	golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect
-	golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
+	golang.org/x/exp v0.0.0-20221028150844-83b7d23a625f // indirect
+	golang.org/x/mod v0.6.0 // indirect
 	golang.org/x/text v0.4.0 // indirect
 	golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect
-	golang.org/x/tools v0.1.12 // indirect
+	golang.org/x/tools v0.2.0 // indirect
 	golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224 // indirect
 	google.golang.org/genproto v0.0.0-20210722135532-667f2b7c528f // indirect
-	gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
 	lukechampine.com/blake3 v1.1.7 // indirect
 )

+ 22 - 58
go.sum

@@ -16,8 +16,8 @@ github.com/caddyserver/certmagic v0.17.2 h1:o30seC1T/dBqBCNNGNHWwj2i5/I/FMjBbTAh
 github.com/caddyserver/certmagic v0.17.2/go.mod h1:ouWUuC490GOLJzkyN35eXfV8bSbwMwSf4bdhkIxtdQE=
 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
-github.com/cloudflare/circl v1.2.1-0.20220831060716-4cf0150356fc h1:307gdRLiZ08dwOIKwc5lAQ19DRFaQQvdhHalyB4Asx8=
-github.com/cloudflare/circl v1.2.1-0.20220831060716-4cf0150356fc/go.mod h1:+CauBF6R70Jqcyl8N2hC8pAXYbWkGIezuSbuGLtRhnw=
+github.com/cloudflare/circl v1.2.1-0.20221019164342-6ab4dfed8f3c h1:K1VdSnBZiGapczwcUKnE1qcsMBclA84DUOD2NG/78VY=
+github.com/cloudflare/circl v1.2.1-0.20221019164342-6ab4dfed8f3c/go.mod h1:+CauBF6R70Jqcyl8N2hC8pAXYbWkGIezuSbuGLtRhnw=
 github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
 github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
 github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
@@ -38,8 +38,6 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
 github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
 github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
 github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
-github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
-github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
 github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
 github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
 github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
@@ -49,14 +47,11 @@ github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4=
 github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
 github.com/go-chi/render v1.0.2 h1:4ER/udB0+fMWB2Jlf15RV3F4A2FDuYi/9f+lFttR/Lg=
 github.com/go-chi/render v1.0.2/go.mod h1:/gr3hVkmYR0YlEy3LxCuVRFzEu9Ruok+gFqbIofjao0=
-github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
-github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
 github.com/gofrs/uuid v4.3.0+incompatible h1:CaSVZxm5B+7o45rtab4jC2G37WGYX1zQfuU2i6DSvnc=
 github.com/gofrs/uuid v4.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
 github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
 github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
-github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
 github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
@@ -84,7 +79,6 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
 github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
 github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE=
 github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
-github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
 github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
 github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
 github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY=
@@ -101,27 +95,18 @@ github.com/libdns/libdns v0.2.1 h1:Wu59T7wSHRgtA0cfxC+n1c/e+O3upJGWytknkmFEDis=
 github.com/libdns/libdns v0.2.1/go.mod h1:yQCXzk1lEZmmCPa857bnk4TsOiqYasqpyOEeSObbb40=
 github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8=
 github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
-github.com/marten-seemann/qpack v0.2.1 h1:jvTsT/HpCn2UZJdP+UUB53FfUUgeOyG5K1ns0OJOGVs=
-github.com/marten-seemann/qpack v0.2.1/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc=
-github.com/marten-seemann/qtls-go1-18 v0.1.2 h1:JH6jmzbduz0ITVQ7ShevK10Av5+jBEKAHMntXmIV7kM=
-github.com/marten-seemann/qtls-go1-18 v0.1.2/go.mod h1:mJttiymBAByA49mhlNZZGrH5u1uXYZJ+RW28Py7f4m4=
-github.com/marten-seemann/qtls-go1-19 v0.1.0 h1:rLFKD/9mp/uq1SYGYuVZhm83wkmU95pK5df3GufyYYU=
-github.com/marten-seemann/qtls-go1-19 v0.1.0/go.mod h1:5HTDWtVudo/WFsHKRNuOhWlbdjrfs5JHrYb0wIJqGpI=
+github.com/marten-seemann/qpack v0.3.0 h1:UiWstOgT8+znlkDPOg2+3rIuYXJ2CnGDkGUXN6ki6hE=
+github.com/marten-seemann/qpack v0.3.0/go.mod h1:cGfKPBiP4a9EQdxCwEwI/GEeWAsjSekBvx/X8mh58+g=
+github.com/marten-seemann/qtls-go1-18 v0.1.3 h1:R4H2Ks8P6pAtUagjFty2p7BVHn3XiwDAl7TTQf5h7TI=
+github.com/marten-seemann/qtls-go1-18 v0.1.3/go.mod h1:mJttiymBAByA49mhlNZZGrH5u1uXYZJ+RW28Py7f4m4=
+github.com/marten-seemann/qtls-go1-19 v0.1.1 h1:mnbxeq3oEyQxQXwI4ReCgW9DPoPR94sNlqWoDZnjRIE=
+github.com/marten-seemann/qtls-go1-19 v0.1.1/go.mod h1:5HTDWtVudo/WFsHKRNuOhWlbdjrfs5JHrYb0wIJqGpI=
 github.com/mholt/acmez v1.0.4 h1:N3cE4Pek+dSolbsofIkAYz6H1d3pE+2G0os7QHslf80=
 github.com/mholt/acmez v1.0.4/go.mod h1:qFGLZ4u+ehWINeJZjzPlsnjJBCPAADWTcIqE/7DAYQY=
 github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA=
 github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
-github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
-github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
-github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
-github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
-github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
-github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
-github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
-github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
-github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
-github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
-github.com/onsi/gomega v1.13.0 h1:7lLHu94wT9Ij0o6EWWclhu0aOh32VxhkwEJvzuWPeak=
+github.com/onsi/ginkgo/v2 v2.3.0 h1:kUMoxMoQG3ogk/QWyKh3zibV7BKZ+xBpWil1cTylVqc=
+github.com/onsi/gomega v1.22.1 h1:pY8O4lBfsHKZHM/6nrxkhVPUznOlIu3quZcKP/M20KI=
 github.com/oschwald/maxminddb-golang v1.10.0 h1:Xp1u0ZhqkSuopaKmk1WwHtjF0H9Hd9181uj2MQ5Vndg=
 github.com/oschwald/maxminddb-golang v1.10.0/go.mod h1:Y2ELenReaLAZ0b400URyGwvYxHV1dLIxBuyOsyYjHK0=
 github.com/pires/go-proxyproto v0.6.2 h1:KAZ7UteSOt6urjme6ZldyFm4wDe/z0ZUP0Yv0Dos0d8=
@@ -137,18 +122,20 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L
 github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 github.com/sagernet/abx-go v0.0.0-20220819185957-dba1257d738e h1:5CFRo8FJbCuf5s/eTBdZpmMbn8Fe2eSMLNAYfKanA34=
 github.com/sagernet/abx-go v0.0.0-20220819185957-dba1257d738e/go.mod h1:qbt0dWObotCfcjAJJ9AxtFPNSDUfZF+6dCpgKEOBn/g=
+github.com/sagernet/cloudflare-tls v0.0.0-20221031050923-d70792f4c3a0 h1:KyhtFFt1Jtp5vW2ohNvstvQffTOQ/s5vENuGXzdA+TM=
+github.com/sagernet/cloudflare-tls v0.0.0-20221031050923-d70792f4c3a0/go.mod h1:D4SFEOkJK+4W1v86ZhX0jPM0rAL498fyQAChqMtes/I=
 github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61 h1:5+m7c6AkmAylhauulqN/c5dnh8/KssrE9c93TQrXldA=
 github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61/go.mod h1:QUQ4RRHD6hGGHdFMEtR8T2P6GS6R3D/CXKdaYHKKXms=
 github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 h1:iL5gZI3uFp0X6EslacyapiRz7LLSJyr4RajF/BhMVyE=
 github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
-github.com/sagernet/quic-go v0.0.0-20220818150011-de611ab3e2bb h1:wc0yQ+SBn4TaTYRwpwvEm3nc4eRdxk6vtRbouLVZAzk=
-github.com/sagernet/quic-go v0.0.0-20220818150011-de611ab3e2bb/go.mod h1:MIccjRKnPTjWwAOpl+AUGWOkzyTd9tERytudxu+1ra4=
+github.com/sagernet/quic-go v0.0.0-20221031051350-29d8bb1c8127 h1:rraPfWlUy2cdZ61FLXRCFbL0lb7oocScbr4Ac0rIzTU=
+github.com/sagernet/quic-go v0.0.0-20221031051350-29d8bb1c8127/go.mod h1:oWFbojDMm85/Jbm/fyWoo8Pux6dIssxGi3q1r+5642A=
 github.com/sagernet/sing v0.0.0-20220812082120-05f9836bff8f/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
 github.com/sagernet/sing v0.0.0-20220817130738-ce854cda8522/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
 github.com/sagernet/sing v0.0.0-20221008120626-60a9910eefe4 h1:LO7xMvMGhYmjQg2vjhTzsODyzs9/WLYu5Per+/8jIeo=
 github.com/sagernet/sing v0.0.0-20221008120626-60a9910eefe4/go.mod h1:zvgDYKI+vCAW9RyfyrKTgleI+DOa8lzHMPC7VZo3OL4=
-github.com/sagernet/sing-dns v0.0.0-20221029093630-568471e6216d h1:U/oM43D++tdv2r9OfHbcd4Q1pMCs8+HW7hPkAD2rrvk=
-github.com/sagernet/sing-dns v0.0.0-20221029093630-568471e6216d/go.mod h1:SrvWLfOSlnFmH32CWXicfilAGgIXR0VjrH6yRbuXYww=
+github.com/sagernet/sing-dns v0.0.0-20221031055845-7de76401d403 h1:kKDO97rx+JVJ4HI1hTWOnCCI6um5clK1LfnIto2DY4M=
+github.com/sagernet/sing-dns v0.0.0-20221031055845-7de76401d403/go.mod h1:cyL9DHbBZ0Xlt/8VD0i6yeiDayH0KzWGNQb8MYhhz7g=
 github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6 h1:JJfDeYYhWunvtxsU/mOVNTmFQmnzGx9dY034qG6G3g4=
 github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6/go.mod h1:EX3RbZvrwAkPI2nuGa78T2iQXmrkT+/VQtskjou42xM=
 github.com/sagernet/sing-tun v0.0.0-20221028015259-ea5c35f62f07 h1:zupkkVVFWv0QsLPjxEzlzXlLfDk1hUujK8ctJSIKFCI=
@@ -175,7 +162,6 @@ github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKs
 github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
 github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 h1:gga7acRE695APm9hlsSMoOoE65U4/TcqNj90mc69Rlg=
 github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
-github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
 go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=
 go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
@@ -201,30 +187,25 @@ golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0
 golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU=
 golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
-golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA=
-golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA=
+golang.org/x/exp v0.0.0-20221028150844-83b7d23a625f h1:Al51T6tzvuh3oiwX11vex3QgJ2XTedFPGmbEVh8cdoc=
+golang.org/x/exp v0.0.0-20221028150844-83b7d23a625f/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
 golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
 golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
 golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
 golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
 golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
 golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
-golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
-golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I=
+golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
 golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
-golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
 golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
@@ -240,24 +221,16 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde h1:ejfdSekXMDxDLbRrJMwUk6KnSLZ2McaUCVcIKM+N6jc=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -274,7 +247,6 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.1.0 h1:g6Z6vPFA9dYBAF7DWcH6sCcOntplXsDKcliusYijMlw=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
@@ -290,12 +262,10 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3
 golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
-golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
-golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE=
+golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -338,15 +308,9 @@ google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
-gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
-gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
-gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

+ 0 - 7
transport/cloudflaretls/README.md

@@ -1,7 +0,0 @@
-# cloudflare-tls
-
-kanged from https://github.com/cloudflare/go
-branch: cf
-commit: 4d2a840e50d2b4316aa19934271832d080c44f7f
-go: 1.18.5
-changes: use github.com/cloudflare/circl 4cf0150356fc62a0ea5c0eec2f64b756cb404145

+ 0 - 101
transport/cloudflaretls/alert.go

@@ -1,101 +0,0 @@
-// Copyright 2009 The Go Authors. 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 "strconv"
-
-type alert uint8
-
-const (
-	// alert level
-	alertLevelWarning = 1
-	alertLevelError   = 2
-)
-
-const (
-	alertCloseNotify                  alert = 0
-	alertUnexpectedMessage            alert = 10
-	alertBadRecordMAC                 alert = 20
-	alertDecryptionFailed             alert = 21
-	alertRecordOverflow               alert = 22
-	alertDecompressionFailure         alert = 30
-	alertHandshakeFailure             alert = 40
-	alertBadCertificate               alert = 42
-	alertUnsupportedCertificate       alert = 43
-	alertCertificateRevoked           alert = 44
-	alertCertificateExpired           alert = 45
-	alertCertificateUnknown           alert = 46
-	alertIllegalParameter             alert = 47
-	alertUnknownCA                    alert = 48
-	alertAccessDenied                 alert = 49
-	alertDecodeError                  alert = 50
-	alertDecryptError                 alert = 51
-	alertExportRestriction            alert = 60
-	alertProtocolVersion              alert = 70
-	alertInsufficientSecurity         alert = 71
-	alertInternalError                alert = 80
-	alertInappropriateFallback        alert = 86
-	alertUserCanceled                 alert = 90
-	alertNoRenegotiation              alert = 100
-	alertMissingExtension             alert = 109
-	alertUnsupportedExtension         alert = 110
-	alertCertificateUnobtainable      alert = 111
-	alertUnrecognizedName             alert = 112
-	alertBadCertificateStatusResponse alert = 113
-	alertBadCertificateHashValue      alert = 114
-	alertUnknownPSKIdentity           alert = 115
-	alertCertificateRequired          alert = 116
-	alertNoApplicationProtocol        alert = 120
-	alertECHRequired                  alert = 121
-)
-
-var alertText = map[alert]string{
-	alertCloseNotify:                  "close notify",
-	alertUnexpectedMessage:            "unexpected message",
-	alertBadRecordMAC:                 "bad record MAC",
-	alertDecryptionFailed:             "decryption failed",
-	alertRecordOverflow:               "record overflow",
-	alertDecompressionFailure:         "decompression failure",
-	alertHandshakeFailure:             "handshake failure",
-	alertBadCertificate:               "bad certificate",
-	alertUnsupportedCertificate:       "unsupported certificate",
-	alertCertificateRevoked:           "revoked certificate",
-	alertCertificateExpired:           "expired certificate",
-	alertCertificateUnknown:           "unknown certificate",
-	alertIllegalParameter:             "illegal parameter",
-	alertUnknownCA:                    "unknown certificate authority",
-	alertAccessDenied:                 "access denied",
-	alertDecodeError:                  "error decoding message",
-	alertDecryptError:                 "error decrypting message",
-	alertExportRestriction:            "export restriction",
-	alertProtocolVersion:              "protocol version not supported",
-	alertInsufficientSecurity:         "insufficient security level",
-	alertInternalError:                "internal error",
-	alertInappropriateFallback:        "inappropriate fallback",
-	alertUserCanceled:                 "user canceled",
-	alertNoRenegotiation:              "no renegotiation",
-	alertMissingExtension:             "missing extension",
-	alertUnsupportedExtension:         "unsupported extension",
-	alertCertificateUnobtainable:      "certificate unobtainable",
-	alertUnrecognizedName:             "unrecognized name",
-	alertBadCertificateStatusResponse: "bad certificate status response",
-	alertBadCertificateHashValue:      "bad certificate hash value",
-	alertUnknownPSKIdentity:           "unknown PSK identity",
-	alertCertificateRequired:          "certificate required",
-	alertNoApplicationProtocol:        "no application protocol",
-	alertECHRequired:                  "ECH required",
-}
-
-func (e alert) String() string {
-	s, ok := alertText[e]
-	if ok {
-		return "tls: " + s
-	}
-	return "tls: alert(" + strconv.Itoa(int(e)) + ")"
-}
-
-func (e alert) Error() string {
-	return e.String()
-}

+ 0 - 345
transport/cloudflaretls/auth.go

@@ -1,345 +0,0 @@
-// Copyright 2017 The Go Authors. 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 (
-	"bytes"
-	"crypto"
-	"crypto/ecdsa"
-	"crypto/ed25519"
-	"crypto/elliptic"
-	"crypto/rsa"
-	"errors"
-	"fmt"
-	"hash"
-	"io"
-
-	circlPki "github.com/cloudflare/circl/pki"
-	circlSign "github.com/cloudflare/circl/sign"
-)
-
-// verifyHandshakeSignature verifies a signature against pre-hashed
-// (if required) handshake contents.
-func verifyHandshakeSignature(sigType uint8, pubkey crypto.PublicKey, hashFunc crypto.Hash, signed, sig []byte) error {
-	switch sigType {
-	case signatureECDSA:
-		pubKey, ok := pubkey.(*ecdsa.PublicKey)
-		if !ok {
-			return fmt.Errorf("expected an ECDSA public key, got %T", pubkey)
-		}
-		if !ecdsa.VerifyASN1(pubKey, signed, sig) {
-			return errors.New("ECDSA verification failure")
-		}
-	case signatureEd25519:
-		pubKey, ok := pubkey.(ed25519.PublicKey)
-		if !ok {
-			return fmt.Errorf("expected an Ed25519 public key, got %T", pubkey)
-		}
-		if !ed25519.Verify(pubKey, signed, sig) {
-			return errors.New("Ed25519 verification failure")
-		}
-	case signaturePKCS1v15:
-		pubKey, ok := pubkey.(*rsa.PublicKey)
-		if !ok {
-			return fmt.Errorf("expected an RSA public key, got %T", pubkey)
-		}
-		if err := rsa.VerifyPKCS1v15(pubKey, hashFunc, signed, sig); err != nil {
-			return err
-		}
-	case signatureRSAPSS:
-		pubKey, ok := pubkey.(*rsa.PublicKey)
-		if !ok {
-			return fmt.Errorf("expected an RSA public key, got %T", pubkey)
-		}
-		signOpts := &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash}
-		if err := rsa.VerifyPSS(pubKey, hashFunc, signed, sig, signOpts); err != nil {
-			return err
-		}
-	default:
-		scheme := circlSchemeBySigType(sigType)
-		if scheme == nil {
-			return errors.New("internal error: unknown signature type")
-		}
-		pubKey, ok := pubkey.(circlSign.PublicKey)
-		if !ok {
-			return fmt.Errorf("expected a %s public key, got %T", scheme.Name(), pubkey)
-		}
-		if !scheme.Verify(pubKey, signed, sig, nil) {
-			return fmt.Errorf("%s verification failure", scheme.Name())
-		}
-	}
-	return nil
-}
-
-const (
-	serverSignatureContext = "TLS 1.3, server CertificateVerify\x00"
-	clientSignatureContext = "TLS 1.3, client CertificateVerify\x00"
-)
-
-var signaturePadding = []byte{
-	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-}
-
-// signedMessage returns the pre-hashed (if necessary) message to be signed by
-// certificate keys in TLS 1.3. See RFC 8446, Section 4.4.3.
-func signedMessage(sigHash crypto.Hash, context string, transcript hash.Hash) []byte {
-	if sigHash == directSigning {
-		b := &bytes.Buffer{}
-		b.Write(signaturePadding)
-		io.WriteString(b, context)
-		b.Write(transcript.Sum(nil))
-		return b.Bytes()
-	}
-	h := sigHash.New()
-	h.Write(signaturePadding)
-	io.WriteString(h, context)
-	h.Write(transcript.Sum(nil))
-	return h.Sum(nil)
-}
-
-// typeAndHashFromSignatureScheme returns the corresponding signature type and
-// crypto.Hash for a given TLS SignatureScheme.
-func typeAndHashFromSignatureScheme(signatureAlgorithm SignatureScheme) (sigType uint8, hash crypto.Hash, err error) {
-	switch signatureAlgorithm {
-	case PKCS1WithSHA1, PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512:
-		sigType = signaturePKCS1v15
-	case PSSWithSHA256, PSSWithSHA384, PSSWithSHA512:
-		sigType = signatureRSAPSS
-	case ECDSAWithSHA1, ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512:
-		sigType = signatureECDSA
-	case Ed25519:
-		sigType = signatureEd25519
-	default:
-		scheme := circlPki.SchemeByTLSID(uint(signatureAlgorithm))
-		if scheme == nil {
-			return 0, 0, fmt.Errorf("unsupported signature algorithm: %v", signatureAlgorithm)
-		}
-		sigType = sigTypeByCirclScheme(scheme)
-		if sigType == 0 {
-			return 0, 0, fmt.Errorf("github.com/cloudflare/circl scheme %s not supported",
-				scheme.Name())
-		}
-	}
-	switch signatureAlgorithm {
-	case PKCS1WithSHA1, ECDSAWithSHA1:
-		hash = crypto.SHA1
-	case PKCS1WithSHA256, PSSWithSHA256, ECDSAWithP256AndSHA256:
-		hash = crypto.SHA256
-	case PKCS1WithSHA384, PSSWithSHA384, ECDSAWithP384AndSHA384:
-		hash = crypto.SHA384
-	case PKCS1WithSHA512, PSSWithSHA512, ECDSAWithP521AndSHA512:
-		hash = crypto.SHA512
-	case Ed25519:
-		hash = directSigning
-	default:
-		scheme := circlPki.SchemeByTLSID(uint(signatureAlgorithm))
-		if scheme == nil {
-			return 0, 0, fmt.Errorf("unsupported signature algorithm: %v", signatureAlgorithm)
-		}
-		hash = directSigning
-	}
-	return sigType, hash, nil
-}
-
-// legacyTypeAndHashFromPublicKey returns the fixed signature type and crypto.Hash for
-// a given public key used with TLS 1.0 and 1.1, before the introduction of
-// signature algorithm negotiation.
-func legacyTypeAndHashFromPublicKey(pub crypto.PublicKey) (sigType uint8, hash crypto.Hash, err error) {
-	switch pub.(type) {
-	case *rsa.PublicKey:
-		return signaturePKCS1v15, crypto.MD5SHA1, nil
-	case *ecdsa.PublicKey:
-		return signatureECDSA, crypto.SHA1, nil
-	case ed25519.PublicKey:
-		// RFC 8422 specifies support for Ed25519 in TLS 1.0 and 1.1,
-		// but it requires holding on to a handshake transcript to do a
-		// full signature, and not even OpenSSL bothers with the
-		// complexity, so we can't even test it properly.
-		return 0, 0, fmt.Errorf("tls: Ed25519 public keys are not supported before TLS 1.2")
-	case circlSign.PublicKey:
-		return 0, 0, fmt.Errorf("tls: circl public keys are not supported before TLS 1.2")
-	default:
-		return 0, 0, fmt.Errorf("tls: unsupported public key: %T", pub)
-	}
-}
-
-var rsaSignatureSchemes = []struct {
-	scheme          SignatureScheme
-	minModulusBytes int
-	maxVersion      uint16
-}{
-	// RSA-PSS is used with PSSSaltLengthEqualsHash, and requires
-	//    emLen >= hLen + sLen + 2
-	{PSSWithSHA256, crypto.SHA256.Size()*2 + 2, VersionTLS13},
-	{PSSWithSHA384, crypto.SHA384.Size()*2 + 2, VersionTLS13},
-	{PSSWithSHA512, crypto.SHA512.Size()*2 + 2, VersionTLS13},
-	// PKCS #1 v1.5 uses prefixes from hashPrefixes in crypto/rsa, and requires
-	//    emLen >= len(prefix) + hLen + 11
-	// TLS 1.3 dropped support for PKCS #1 v1.5 in favor of RSA-PSS.
-	{PKCS1WithSHA256, 19 + crypto.SHA256.Size() + 11, VersionTLS12},
-	{PKCS1WithSHA384, 19 + crypto.SHA384.Size() + 11, VersionTLS12},
-	{PKCS1WithSHA512, 19 + crypto.SHA512.Size() + 11, VersionTLS12},
-	{PKCS1WithSHA1, 15 + crypto.SHA1.Size() + 11, VersionTLS12},
-}
-
-// signatureSchemesForCertificate returns the list of supported SignatureSchemes
-// for a given certificate, based on the public key and the protocol version,
-// and optionally filtered by its explicit SupportedSignatureAlgorithms.
-//
-// This function must be kept in sync with supportedSignatureAlgorithms.
-func signatureSchemesForCertificate(version uint16, cert *Certificate) []SignatureScheme {
-	priv, ok := cert.PrivateKey.(crypto.Signer)
-	if !ok {
-		return nil
-	}
-
-	var sigAlgs []SignatureScheme
-	switch pub := priv.Public().(type) {
-	case *ecdsa.PublicKey:
-		if version != VersionTLS13 {
-			// In TLS 1.2 and earlier, ECDSA algorithms are not
-			// constrained to a single curve.
-			sigAlgs = []SignatureScheme{
-				ECDSAWithP256AndSHA256,
-				ECDSAWithP384AndSHA384,
-				ECDSAWithP521AndSHA512,
-				ECDSAWithSHA1,
-			}
-			break
-		}
-		switch pub.Curve {
-		case elliptic.P256():
-			sigAlgs = []SignatureScheme{ECDSAWithP256AndSHA256}
-		case elliptic.P384():
-			sigAlgs = []SignatureScheme{ECDSAWithP384AndSHA384}
-		case elliptic.P521():
-			sigAlgs = []SignatureScheme{ECDSAWithP521AndSHA512}
-		default:
-			return nil
-		}
-	case *rsa.PublicKey:
-		size := pub.Size()
-		sigAlgs = make([]SignatureScheme, 0, len(rsaSignatureSchemes))
-		for _, candidate := range rsaSignatureSchemes {
-			if size >= candidate.minModulusBytes && version <= candidate.maxVersion {
-				sigAlgs = append(sigAlgs, candidate.scheme)
-			}
-		}
-	case ed25519.PublicKey:
-		sigAlgs = []SignatureScheme{Ed25519}
-	case circlSign.PublicKey:
-		scheme := pub.Scheme()
-		tlsScheme, ok := scheme.(circlPki.TLSScheme)
-		if !ok {
-			return nil
-		}
-		sigAlgs = []SignatureScheme{SignatureScheme(tlsScheme.TLSIdentifier())}
-	default:
-		return nil
-	}
-
-	if cert.SupportedSignatureAlgorithms != nil {
-		var filteredSigAlgs []SignatureScheme
-		for _, sigAlg := range sigAlgs {
-			if isSupportedSignatureAlgorithm(sigAlg, cert.SupportedSignatureAlgorithms) {
-				filteredSigAlgs = append(filteredSigAlgs, sigAlg)
-			}
-		}
-		return filteredSigAlgs
-	}
-	return sigAlgs
-}
-
-// selectSignatureSchemeDC picks a SignatureScheme from the peer's preference list
-// that works with the selected delegated credential. It's only called for protocol
-// versions that support delegated credential, so TLS 1.3.
-func selectSignatureSchemeDC(vers uint16, dc *DelegatedCredential, peerAlgs []SignatureScheme, peerAlgsDC []SignatureScheme) (SignatureScheme, error) {
-	if vers != VersionTLS13 {
-		return 0, errors.New("unsupported TLS version for dc")
-	}
-
-	if !isSupportedSignatureAlgorithm(dc.algorithm, peerAlgs) {
-		return undefinedSignatureScheme, errors.New("tls: peer doesn't support the delegated credential's signature")
-	}
-
-	// Pick signature scheme in the peer's preference order, as our
-	// preference order is not configurable.
-	for _, preferredAlg := range peerAlgsDC {
-		if preferredAlg == dc.cred.expCertVerfAlgo {
-			return preferredAlg, nil
-		}
-	}
-	return 0, errors.New("tls: peer doesn't support the delegated credential's signature algorithm")
-}
-
-// selectSignatureScheme picks a SignatureScheme from the peer's preference list
-// that works with the selected certificate. It's only called for protocol
-// versions that support signature algorithms, so TLS 1.2 and 1.3.
-func selectSignatureScheme(vers uint16, c *Certificate, peerAlgs []SignatureScheme) (SignatureScheme, error) {
-	supportedAlgs := signatureSchemesForCertificate(vers, c)
-	if len(supportedAlgs) == 0 {
-		return 0, unsupportedCertificateError(c)
-	}
-	if len(peerAlgs) == 0 && vers == VersionTLS12 {
-		// For TLS 1.2, if the client didn't send signature_algorithms then we
-		// can assume that it supports SHA1. See RFC 5246, Section 7.4.1.4.1.
-		peerAlgs = []SignatureScheme{PKCS1WithSHA1, ECDSAWithSHA1}
-	}
-	// Pick signature scheme in the peer's preference order, as our
-	// preference order is not configurable.
-	for _, preferredAlg := range peerAlgs {
-		if isSupportedSignatureAlgorithm(preferredAlg, supportedAlgs) {
-			return preferredAlg, nil
-		}
-	}
-	return 0, errors.New("tls: peer doesn't support any of the certificate's signature algorithms")
-}
-
-// unsupportedCertificateError returns a helpful error for certificates with
-// an unsupported private key.
-func unsupportedCertificateError(cert *Certificate) error {
-	switch cert.PrivateKey.(type) {
-	case rsa.PrivateKey, ecdsa.PrivateKey:
-		return fmt.Errorf("tls: unsupported certificate: private key is %T, expected *%T",
-			cert.PrivateKey, cert.PrivateKey)
-	case *ed25519.PrivateKey:
-		return fmt.Errorf("tls: unsupported certificate: private key is *ed25519.PrivateKey, expected ed25519.PrivateKey")
-	}
-
-	signer, ok := cert.PrivateKey.(crypto.Signer)
-	if !ok {
-		return fmt.Errorf("tls: certificate private key (%T) does not implement crypto.Signer",
-			cert.PrivateKey)
-	}
-
-	switch pub := signer.Public().(type) {
-	case *ecdsa.PublicKey:
-		switch pub.Curve {
-		case elliptic.P256():
-		case elliptic.P384():
-		case elliptic.P521():
-		default:
-			return fmt.Errorf("tls: unsupported certificate curve (%s)", pub.Curve.Params().Name)
-		}
-	case *rsa.PublicKey:
-		return fmt.Errorf("tls: certificate RSA key size too small for supported signature algorithms")
-	case ed25519.PublicKey:
-	default:
-		return fmt.Errorf("tls: unsupported certificate key (%T)", pub)
-	}
-
-	if cert.SupportedSignatureAlgorithms != nil {
-		return fmt.Errorf("tls: peer doesn't support the certificate custom signature algorithms")
-	}
-
-	return fmt.Errorf("tls: internal error: unsupported key (%T)", cert.PrivateKey)
-}

+ 0 - 104
transport/cloudflaretls/cfkem.go

@@ -1,104 +0,0 @@
-// Copyright 2022 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.
-//
-// Glue to add Circl's (post-quantum) hybrid KEMs.
-//
-// To enable set CurvePreferences with the desired scheme as the first element:
-//
-//   import (
-//      "github.com/cloudflare/circl/kem/tls"
-//      "github.com/cloudflare/circl/kem/hybrid"
-//
-//          [...]
-//
-//   config.CurvePreferences = []tls.CurveID{
-//      hybrid.X25519Kyber512Draft00().(tls.TLSScheme).TLSCurveID(),
-//      tls.X25519,
-//      tls.P256,
-//   }
-
-package tls
-
-import (
-	"fmt"
-	"io"
-
-	"github.com/cloudflare/circl/kem"
-	"github.com/cloudflare/circl/kem/hybrid"
-)
-
-// Either ecdheParameters or kem.PrivateKey
-type clientKeySharePrivate interface{}
-
-var (
-	X25519Kyber512Draft00 = CurveID(0xfe30)
-	X25519Kyber768Draft00 = CurveID(0xfe31)
-	invalidCurveID        = CurveID(0)
-)
-
-func kemSchemeKeyToCurveID(s kem.Scheme) CurveID {
-	switch s.Name() {
-	case "Kyber512-X25519":
-		return X25519Kyber512Draft00
-	case "Kyber768-X25519":
-		return X25519Kyber768Draft00
-	default:
-		return invalidCurveID
-	}
-}
-
-// Extract CurveID from clientKeySharePrivate
-func clientKeySharePrivateCurveID(ks clientKeySharePrivate) CurveID {
-	switch v := ks.(type) {
-	case kem.PrivateKey:
-		ret := kemSchemeKeyToCurveID(v.Scheme())
-		if ret == invalidCurveID {
-			panic("cfkem: internal error: don't know CurveID for this KEM")
-		}
-		return ret
-	case ecdheParameters:
-		return v.CurveID()
-	default:
-		panic("cfkem: internal error: unknown clientKeySharePrivate")
-	}
-}
-
-// Returns scheme by CurveID if supported by Circl
-func curveIdToCirclScheme(id CurveID) kem.Scheme {
-	switch id {
-	case X25519Kyber512Draft00:
-		return hybrid.Kyber512X25519()
-	case X25519Kyber768Draft00:
-		return hybrid.Kyber768X25519()
-	}
-	return nil
-}
-
-// Generate a new shared secret and encapsulates it for the packed
-// public key in ppk using randomness from rnd.
-func encapsulateForKem(scheme kem.Scheme, rnd io.Reader, ppk []byte) (
-	ct, ss []byte, alert alert, err error,
-) {
-	pk, err := scheme.UnmarshalBinaryPublicKey(ppk)
-	if err != nil {
-		return nil, nil, alertIllegalParameter, fmt.Errorf("unpack pk: %w", err)
-	}
-	seed := make([]byte, scheme.EncapsulationSeedSize())
-	if _, err := io.ReadFull(rnd, seed); err != nil {
-		return nil, nil, alertInternalError, fmt.Errorf("random: %w", err)
-	}
-	ct, ss, err = scheme.EncapsulateDeterministically(pk, seed)
-	return ct, ss, alertIllegalParameter, err
-}
-
-// Generate a new keypair using randomness from rnd.
-func generateKemKeyPair(scheme kem.Scheme, rnd io.Reader) (
-	kem.PublicKey, kem.PrivateKey, error,
-) {
-	seed := make([]byte, scheme.SeedSize())
-	if _, err := io.ReadFull(rnd, seed); err != nil {
-		return nil, nil, err
-	}
-	pk, sk := scheme.DeriveKeyPair(seed)
-	return pk, sk, nil
-}

+ 0 - 688
transport/cloudflaretls/cipher_suites.go

@@ -1,688 +0,0 @@
-// Copyright 2010 The Go Authors. 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 (
-	"crypto"
-	"crypto/aes"
-	"crypto/cipher"
-	"crypto/des"
-	"crypto/hmac"
-	"crypto/rc4"
-	"crypto/sha1"
-	"crypto/sha256"
-	"fmt"
-	"hash"
-	"runtime"
-
-	"golang.org/x/crypto/chacha20poly1305"
-	"golang.org/x/sys/cpu"
-)
-
-// CipherSuite is a TLS cipher suite. Note that most functions in this package
-// accept and expose cipher suite IDs instead of this type.
-type CipherSuite struct {
-	ID   uint16
-	Name string
-
-	// Supported versions is the list of TLS protocol versions that can
-	// negotiate this cipher suite.
-	SupportedVersions []uint16
-
-	// Insecure is true if the cipher suite has known security issues
-	// due to its primitives, design, or implementation.
-	Insecure bool
-}
-
-var (
-	supportedUpToTLS12 = []uint16{VersionTLS10, VersionTLS11, VersionTLS12}
-	supportedOnlyTLS12 = []uint16{VersionTLS12}
-	supportedOnlyTLS13 = []uint16{VersionTLS13}
-)
-
-// CipherSuites returns a list of cipher suites currently implemented by this
-// package, excluding those with security issues, which are returned by
-// InsecureCipherSuites.
-//
-// The list is sorted by ID. Note that the default cipher suites selected by
-// this package might depend on logic that can't be captured by a static list,
-// and might not match those returned by this function.
-func CipherSuites() []*CipherSuite {
-	return []*CipherSuite{
-		{TLS_RSA_WITH_AES_128_CBC_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA", supportedUpToTLS12, false},
-		{TLS_RSA_WITH_AES_256_CBC_SHA, "TLS_RSA_WITH_AES_256_CBC_SHA", supportedUpToTLS12, false},
-		{TLS_RSA_WITH_AES_128_GCM_SHA256, "TLS_RSA_WITH_AES_128_GCM_SHA256", supportedOnlyTLS12, false},
-		{TLS_RSA_WITH_AES_256_GCM_SHA384, "TLS_RSA_WITH_AES_256_GCM_SHA384", supportedOnlyTLS12, false},
-
-		{TLS_AES_128_GCM_SHA256, "TLS_AES_128_GCM_SHA256", supportedOnlyTLS13, false},
-		{TLS_AES_256_GCM_SHA384, "TLS_AES_256_GCM_SHA384", supportedOnlyTLS13, false},
-		{TLS_CHACHA20_POLY1305_SHA256, "TLS_CHACHA20_POLY1305_SHA256", supportedOnlyTLS13, false},
-
-		{TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", supportedUpToTLS12, false},
-		{TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", supportedUpToTLS12, false},
-		{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", supportedUpToTLS12, false},
-		{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", supportedUpToTLS12, false},
-		{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", supportedOnlyTLS12, false},
-		{TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", supportedOnlyTLS12, false},
-		{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", supportedOnlyTLS12, false},
-		{TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", supportedOnlyTLS12, false},
-		{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", supportedOnlyTLS12, false},
-		{TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", supportedOnlyTLS12, false},
-	}
-}
-
-// InsecureCipherSuites returns a list of cipher suites currently implemented by
-// this package and which have security issues.
-//
-// Most applications should not use the cipher suites in this list, and should
-// only use those returned by CipherSuites.
-func InsecureCipherSuites() []*CipherSuite {
-	// This list includes RC4, CBC_SHA256, and 3DES cipher suites. See
-	// cipherSuitesPreferenceOrder for details.
-	return []*CipherSuite{
-		{TLS_RSA_WITH_RC4_128_SHA, "TLS_RSA_WITH_RC4_128_SHA", supportedUpToTLS12, true},
-		{TLS_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA", supportedUpToTLS12, true},
-		{TLS_RSA_WITH_AES_128_CBC_SHA256, "TLS_RSA_WITH_AES_128_CBC_SHA256", supportedOnlyTLS12, true},
-		{TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", supportedUpToTLS12, true},
-		{TLS_ECDHE_RSA_WITH_RC4_128_SHA, "TLS_ECDHE_RSA_WITH_RC4_128_SHA", supportedUpToTLS12, true},
-		{TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", supportedUpToTLS12, true},
-		{TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", supportedOnlyTLS12, true},
-		{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", supportedOnlyTLS12, true},
-	}
-}
-
-// CipherSuiteName returns the standard name for the passed cipher suite ID
-// (e.g. "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"), or a fallback representation
-// of the ID value if the cipher suite is not implemented by this package.
-func CipherSuiteName(id uint16) string {
-	for _, c := range CipherSuites() {
-		if c.ID == id {
-			return c.Name
-		}
-	}
-	for _, c := range InsecureCipherSuites() {
-		if c.ID == id {
-			return c.Name
-		}
-	}
-	return fmt.Sprintf("0x%04X", id)
-}
-
-const (
-	// suiteECDHE indicates that the cipher suite involves elliptic curve
-	// Diffie-Hellman. This means that it should only be selected when the
-	// client indicates that it supports ECC with a curve and point format
-	// that we're happy with.
-	suiteECDHE = 1 << iota
-	// suiteECSign indicates that the cipher suite involves an ECDSA or
-	// EdDSA signature and therefore may only be selected when the server's
-	// certificate is ECDSA or EdDSA. If this is not set then the cipher suite
-	// is RSA based.
-	suiteECSign
-	// suiteTLS12 indicates that the cipher suite should only be advertised
-	// and accepted when using TLS 1.2.
-	suiteTLS12
-	// suiteSHA384 indicates that the cipher suite uses SHA384 as the
-	// handshake hash.
-	suiteSHA384
-)
-
-// A cipherSuite is a TLS 1.0–1.2 cipher suite, and defines the key exchange
-// mechanism, as well as the cipher+MAC pair or the AEAD.
-type cipherSuite struct {
-	id uint16
-	// the lengths, in bytes, of the key material needed for each component.
-	keyLen int
-	macLen int
-	ivLen  int
-	ka     func(version uint16) keyAgreement
-	// flags is a bitmask of the suite* values, above.
-	flags  int
-	cipher func(key, iv []byte, isRead bool) any
-	mac    func(key []byte) hash.Hash
-	aead   func(key, fixedNonce []byte) aead
-}
-
-var cipherSuites = []*cipherSuite{ // TODO: replace with a map, since the order doesn't matter.
-	{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 32, 0, 12, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadChaCha20Poly1305},
-	{TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, 32, 0, 12, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12, nil, nil, aeadChaCha20Poly1305},
-	{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadAESGCM},
-	{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12, nil, nil, aeadAESGCM},
-	{TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
-	{TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
-	{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, ecdheRSAKA, suiteECDHE | suiteTLS12, cipherAES, macSHA256, nil},
-	{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil},
-	{TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12, cipherAES, macSHA256, nil},
-	{TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECSign, cipherAES, macSHA1, nil},
-	{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil},
-	{TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECSign, cipherAES, macSHA1, nil},
-	{TLS_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, rsaKA, suiteTLS12, nil, nil, aeadAESGCM},
-	{TLS_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, rsaKA, suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
-	{TLS_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, rsaKA, suiteTLS12, cipherAES, macSHA256, nil},
-	{TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil},
-	{TLS_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil},
-	{TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, suiteECDHE, cipher3DES, macSHA1, nil},
-	{TLS_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, rsaKA, 0, cipher3DES, macSHA1, nil},
-	{TLS_RSA_WITH_RC4_128_SHA, 16, 20, 0, rsaKA, 0, cipherRC4, macSHA1, nil},
-	{TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheRSAKA, suiteECDHE, cipherRC4, macSHA1, nil},
-	{TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheECDSAKA, suiteECDHE | suiteECSign, cipherRC4, macSHA1, nil},
-}
-
-// selectCipherSuite returns the first TLS 1.0–1.2 cipher suite from ids which
-// is also in supportedIDs and passes the ok filter.
-func selectCipherSuite(ids, supportedIDs []uint16, ok func(*cipherSuite) bool) *cipherSuite {
-	for _, id := range ids {
-		candidate := cipherSuiteByID(id)
-		if candidate == nil || !ok(candidate) {
-			continue
-		}
-
-		for _, suppID := range supportedIDs {
-			if id == suppID {
-				return candidate
-			}
-		}
-	}
-	return nil
-}
-
-// A cipherSuiteTLS13 defines only the pair of the AEAD algorithm and hash
-// algorithm to be used with HKDF. See RFC 8446, Appendix B.4.
-type cipherSuiteTLS13 struct {
-	id     uint16
-	keyLen int
-	aead   func(key, fixedNonce []byte) aead
-	hash   crypto.Hash
-}
-
-var cipherSuitesTLS13 = []*cipherSuiteTLS13{ // TODO: replace with a map.
-	{TLS_AES_128_GCM_SHA256, 16, aeadAESGCMTLS13, crypto.SHA256},
-	{TLS_CHACHA20_POLY1305_SHA256, 32, aeadChaCha20Poly1305, crypto.SHA256},
-	{TLS_AES_256_GCM_SHA384, 32, aeadAESGCMTLS13, crypto.SHA384},
-}
-
-// cipherSuitesPreferenceOrder is the order in which we'll select (on the
-// server) or advertise (on the client) TLS 1.0–1.2 cipher suites.
-//
-// Cipher suites are filtered but not reordered based on the application and
-// peer's preferences, meaning we'll never select a suite lower in this list if
-// any higher one is available. This makes it more defensible to keep weaker
-// cipher suites enabled, especially on the server side where we get the last
-// word, since there are no known downgrade attacks on cipher suites selection.
-//
-// The list is sorted by applying the following priority rules, stopping at the
-// first (most important) applicable one:
-//
-//   - Anything else comes before RC4
-//
-//     RC4 has practically exploitable biases. See https://www.rc4nomore.com.
-//
-//   - Anything else comes before CBC_SHA256
-//
-//     SHA-256 variants of the CBC ciphersuites don't implement any Lucky13
-//     countermeasures. See http://www.isg.rhul.ac.uk/tls/Lucky13.html and
-//     https://www.imperialviolet.org/2013/02/04/luckythirteen.html.
-//
-//   - Anything else comes before 3DES
-//
-//     3DES has 64-bit blocks, which makes it fundamentally susceptible to
-//     birthday attacks. See https://sweet32.info.
-//
-//   - ECDHE comes before anything else
-//
-//     Once we got the broken stuff out of the way, the most important
-//     property a cipher suite can have is forward secrecy. We don't
-//     implement FFDHE, so that means ECDHE.
-//
-//   - AEADs come before CBC ciphers
-//
-//     Even with Lucky13 countermeasures, MAC-then-Encrypt CBC cipher suites
-//     are fundamentally fragile, and suffered from an endless sequence of
-//     padding oracle attacks. See https://eprint.iacr.org/2015/1129,
-//     https://www.imperialviolet.org/2014/12/08/poodleagain.html, and
-//     https://blog.cloudflare.com/yet-another-padding-oracle-in-openssl-cbc-ciphersuites/.
-//
-//   - AES comes before ChaCha20
-//
-//     When AES hardware is available, AES-128-GCM and AES-256-GCM are faster
-//     than ChaCha20Poly1305.
-//
-//     When AES hardware is not available, AES-128-GCM is one or more of: much
-//     slower, way more complex, and less safe (because not constant time)
-//     than ChaCha20Poly1305.
-//
-//     We use this list if we think both peers have AES hardware, and
-//     cipherSuitesPreferenceOrderNoAES otherwise.
-//
-//   - AES-128 comes before AES-256
-//
-//     The only potential advantages of AES-256 are better multi-target
-//     margins, and hypothetical post-quantum properties. Neither apply to
-//     TLS, and AES-256 is slower due to its four extra rounds (which don't
-//     contribute to the advantages above).
-//
-//   - ECDSA comes before RSA
-//
-//     The relative order of ECDSA and RSA cipher suites doesn't matter,
-//     as they depend on the certificate. Pick one to get a stable order.
-var cipherSuitesPreferenceOrder = []uint16{
-	// AEADs w/ ECDHE
-	TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
-	TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
-	TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
-
-	// CBC w/ ECDHE
-	TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
-	TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
-
-	// AEADs w/o ECDHE
-	TLS_RSA_WITH_AES_128_GCM_SHA256,
-	TLS_RSA_WITH_AES_256_GCM_SHA384,
-
-	// CBC w/o ECDHE
-	TLS_RSA_WITH_AES_128_CBC_SHA,
-	TLS_RSA_WITH_AES_256_CBC_SHA,
-
-	// 3DES
-	TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
-	TLS_RSA_WITH_3DES_EDE_CBC_SHA,
-
-	// CBC_SHA256
-	TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
-	TLS_RSA_WITH_AES_128_CBC_SHA256,
-
-	// RC4
-	TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA,
-	TLS_RSA_WITH_RC4_128_SHA,
-}
-
-var cipherSuitesPreferenceOrderNoAES = []uint16{
-	// ChaCha20Poly1305
-	TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
-
-	// AES-GCM w/ ECDHE
-	TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
-	TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
-
-	// The rest of cipherSuitesPreferenceOrder.
-	TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
-	TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
-	TLS_RSA_WITH_AES_128_GCM_SHA256,
-	TLS_RSA_WITH_AES_256_GCM_SHA384,
-	TLS_RSA_WITH_AES_128_CBC_SHA,
-	TLS_RSA_WITH_AES_256_CBC_SHA,
-	TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
-	TLS_RSA_WITH_3DES_EDE_CBC_SHA,
-	TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
-	TLS_RSA_WITH_AES_128_CBC_SHA256,
-	TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA,
-	TLS_RSA_WITH_RC4_128_SHA,
-}
-
-// disabledCipherSuites are not used unless explicitly listed in
-// Config.CipherSuites. They MUST be at the end of cipherSuitesPreferenceOrder.
-var disabledCipherSuites = []uint16{
-	// CBC_SHA256
-	TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
-	TLS_RSA_WITH_AES_128_CBC_SHA256,
-
-	// RC4
-	TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA,
-	TLS_RSA_WITH_RC4_128_SHA,
-}
-
-var (
-	defaultCipherSuitesLen = len(cipherSuitesPreferenceOrder) - len(disabledCipherSuites)
-	defaultCipherSuites    = cipherSuitesPreferenceOrder[:defaultCipherSuitesLen]
-)
-
-// defaultCipherSuitesTLS13 is also the preference order, since there are no
-// disabled by default TLS 1.3 cipher suites. The same AES vs ChaCha20 logic as
-// cipherSuitesPreferenceOrder applies.
-var defaultCipherSuitesTLS13 = []uint16{
-	TLS_AES_128_GCM_SHA256,
-	TLS_AES_256_GCM_SHA384,
-	TLS_CHACHA20_POLY1305_SHA256,
-}
-
-var defaultCipherSuitesTLS13NoAES = []uint16{
-	TLS_CHACHA20_POLY1305_SHA256,
-	TLS_AES_128_GCM_SHA256,
-	TLS_AES_256_GCM_SHA384,
-}
-
-var (
-	hasGCMAsmAMD64 = cpu.X86.HasAES && cpu.X86.HasPCLMULQDQ
-	hasGCMAsmARM64 = cpu.ARM64.HasAES && cpu.ARM64.HasPMULL
-	// Keep in sync with crypto/aes/cipher_s390x.go.
-	hasGCMAsmS390X = cpu.S390X.HasAES && cpu.S390X.HasAESCBC && cpu.S390X.HasAESCTR &&
-		(cpu.S390X.HasGHASH || cpu.S390X.HasAESGCM)
-
-	hasAESGCMHardwareSupport = runtime.GOARCH == "amd64" && hasGCMAsmAMD64 ||
-		runtime.GOARCH == "arm64" && hasGCMAsmARM64 ||
-		runtime.GOARCH == "s390x" && hasGCMAsmS390X
-)
-
-var aesgcmCiphers = map[uint16]bool{
-	// TLS 1.2
-	TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:   true,
-	TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:   true,
-	TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: true,
-	TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: true,
-	// TLS 1.3
-	TLS_AES_128_GCM_SHA256: true,
-	TLS_AES_256_GCM_SHA384: true,
-}
-
-var nonAESGCMAEADCiphers = map[uint16]bool{
-	// TLS 1.2
-	TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305:   true,
-	TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305: true,
-	// TLS 1.3
-	TLS_CHACHA20_POLY1305_SHA256: true,
-}
-
-// aesgcmPreferred returns whether the first known cipher in the preference list
-// is an AES-GCM cipher, implying the peer has hardware support for it.
-func aesgcmPreferred(ciphers []uint16) bool {
-	for _, cID := range ciphers {
-		if c := cipherSuiteByID(cID); c != nil {
-			return aesgcmCiphers[cID]
-		}
-		if c := cipherSuiteTLS13ByID(cID); c != nil {
-			return aesgcmCiphers[cID]
-		}
-	}
-	return false
-}
-
-func cipherRC4(key, iv []byte, isRead bool) any {
-	cipher, _ := rc4.NewCipher(key)
-	return cipher
-}
-
-func cipher3DES(key, iv []byte, isRead bool) any {
-	block, _ := des.NewTripleDESCipher(key)
-	if isRead {
-		return cipher.NewCBCDecrypter(block, iv)
-	}
-	return cipher.NewCBCEncrypter(block, iv)
-}
-
-func cipherAES(key, iv []byte, isRead bool) any {
-	block, _ := aes.NewCipher(key)
-	if isRead {
-		return cipher.NewCBCDecrypter(block, iv)
-	}
-	return cipher.NewCBCEncrypter(block, iv)
-}
-
-// macSHA1 returns a SHA-1 based constant time MAC.
-func macSHA1(key []byte) hash.Hash {
-	return hmac.New(newConstantTimeHash(sha1.New), key)
-}
-
-// macSHA256 returns a SHA-256 based MAC. This is only supported in TLS 1.2 and
-// is currently only used in disabled-by-default cipher suites.
-func macSHA256(key []byte) hash.Hash {
-	return hmac.New(sha256.New, key)
-}
-
-type aead interface {
-	cipher.AEAD
-
-	// explicitNonceLen returns the number of bytes of explicit nonce
-	// included in each record. This is eight for older AEADs and
-	// zero for modern ones.
-	explicitNonceLen() int
-}
-
-const (
-	aeadNonceLength   = 12
-	noncePrefixLength = 4
-)
-
-// prefixNonceAEAD wraps an AEAD and prefixes a fixed portion of the nonce to
-// each call.
-type prefixNonceAEAD struct {
-	// nonce contains the fixed part of the nonce in the first four bytes.
-	nonce [aeadNonceLength]byte
-	aead  cipher.AEAD
-}
-
-func (f *prefixNonceAEAD) NonceSize() int        { return aeadNonceLength - noncePrefixLength }
-func (f *prefixNonceAEAD) Overhead() int         { return f.aead.Overhead() }
-func (f *prefixNonceAEAD) explicitNonceLen() int { return f.NonceSize() }
-
-func (f *prefixNonceAEAD) Seal(out, nonce, plaintext, additionalData []byte) []byte {
-	copy(f.nonce[4:], nonce)
-	return f.aead.Seal(out, f.nonce[:], plaintext, additionalData)
-}
-
-func (f *prefixNonceAEAD) Open(out, nonce, ciphertext, additionalData []byte) ([]byte, error) {
-	copy(f.nonce[4:], nonce)
-	return f.aead.Open(out, f.nonce[:], ciphertext, additionalData)
-}
-
-// xoredNonceAEAD wraps an AEAD by XORing in a fixed pattern to the nonce
-// before each call.
-type xorNonceAEAD struct {
-	nonceMask [aeadNonceLength]byte
-	aead      cipher.AEAD
-}
-
-func (f *xorNonceAEAD) NonceSize() int        { return 8 } // 64-bit sequence number
-func (f *xorNonceAEAD) Overhead() int         { return f.aead.Overhead() }
-func (f *xorNonceAEAD) explicitNonceLen() int { return 0 }
-
-func (f *xorNonceAEAD) Seal(out, nonce, plaintext, additionalData []byte) []byte {
-	for i, b := range nonce {
-		f.nonceMask[4+i] ^= b
-	}
-	result := f.aead.Seal(out, f.nonceMask[:], plaintext, additionalData)
-	for i, b := range nonce {
-		f.nonceMask[4+i] ^= b
-	}
-
-	return result
-}
-
-func (f *xorNonceAEAD) Open(out, nonce, ciphertext, additionalData []byte) ([]byte, error) {
-	for i, b := range nonce {
-		f.nonceMask[4+i] ^= b
-	}
-	result, err := f.aead.Open(out, f.nonceMask[:], ciphertext, additionalData)
-	for i, b := range nonce {
-		f.nonceMask[4+i] ^= b
-	}
-
-	return result, err
-}
-
-func aeadAESGCM(key, noncePrefix []byte) aead {
-	if len(noncePrefix) != noncePrefixLength {
-		panic("tls: internal error: wrong nonce length")
-	}
-	aes, err := aes.NewCipher(key)
-	if err != nil {
-		panic(err)
-	}
-	aead, err := cipher.NewGCM(aes)
-	if err != nil {
-		panic(err)
-	}
-
-	ret := &prefixNonceAEAD{aead: aead}
-	copy(ret.nonce[:], noncePrefix)
-	return ret
-}
-
-func aeadAESGCMTLS13(key, nonceMask []byte) aead {
-	if len(nonceMask) != aeadNonceLength {
-		panic("tls: internal error: wrong nonce length")
-	}
-	aes, err := aes.NewCipher(key)
-	if err != nil {
-		panic(err)
-	}
-	aead, err := cipher.NewGCM(aes)
-	if err != nil {
-		panic(err)
-	}
-
-	ret := &xorNonceAEAD{aead: aead}
-	copy(ret.nonceMask[:], nonceMask)
-	return ret
-}
-
-func aeadChaCha20Poly1305(key, nonceMask []byte) aead {
-	if len(nonceMask) != aeadNonceLength {
-		panic("tls: internal error: wrong nonce length")
-	}
-	aead, err := chacha20poly1305.New(key)
-	if err != nil {
-		panic(err)
-	}
-
-	ret := &xorNonceAEAD{aead: aead}
-	copy(ret.nonceMask[:], nonceMask)
-	return ret
-}
-
-type constantTimeHash interface {
-	hash.Hash
-	ConstantTimeSum(b []byte) []byte
-}
-
-// cthWrapper wraps any hash.Hash that implements ConstantTimeSum, and replaces
-// with that all calls to Sum. It's used to obtain a ConstantTimeSum-based HMAC.
-type cthWrapper struct {
-	h constantTimeHash
-}
-
-func (c *cthWrapper) Size() int                   { return c.h.Size() }
-func (c *cthWrapper) BlockSize() int              { return c.h.BlockSize() }
-func (c *cthWrapper) Reset()                      { c.h.Reset() }
-func (c *cthWrapper) Write(p []byte) (int, error) { return c.h.Write(p) }
-func (c *cthWrapper) Sum(b []byte) []byte         { return c.h.ConstantTimeSum(b) }
-
-func newConstantTimeHash(h func() hash.Hash) func() hash.Hash {
-	return func() hash.Hash {
-		return &cthWrapper{h().(constantTimeHash)}
-	}
-}
-
-// tls10MAC implements the TLS 1.0 MAC function. RFC 2246, Section 6.2.3.
-func tls10MAC(h hash.Hash, out, seq, header, data, extra []byte) []byte {
-	h.Reset()
-	h.Write(seq)
-	h.Write(header)
-	h.Write(data)
-	res := h.Sum(out)
-	if extra != nil {
-		h.Write(extra)
-	}
-	return res
-}
-
-func rsaKA(version uint16) keyAgreement {
-	return rsaKeyAgreement{}
-}
-
-func ecdheECDSAKA(version uint16) keyAgreement {
-	return &ecdheKeyAgreement{
-		isRSA:   false,
-		version: version,
-	}
-}
-
-func ecdheRSAKA(version uint16) keyAgreement {
-	return &ecdheKeyAgreement{
-		isRSA:   true,
-		version: version,
-	}
-}
-
-// mutualCipherSuite returns a cipherSuite given a list of supported
-// ciphersuites and the id requested by the peer.
-func mutualCipherSuite(have []uint16, want uint16) *cipherSuite {
-	for _, id := range have {
-		if id == want {
-			return cipherSuiteByID(id)
-		}
-	}
-	return nil
-}
-
-func cipherSuiteByID(id uint16) *cipherSuite {
-	for _, cipherSuite := range cipherSuites {
-		if cipherSuite.id == id {
-			return cipherSuite
-		}
-	}
-	return nil
-}
-
-func mutualCipherSuiteTLS13(have []uint16, want uint16) *cipherSuiteTLS13 {
-	for _, id := range have {
-		if id == want {
-			return cipherSuiteTLS13ByID(id)
-		}
-	}
-	return nil
-}
-
-func cipherSuiteTLS13ByID(id uint16) *cipherSuiteTLS13 {
-	for _, cipherSuite := range cipherSuitesTLS13 {
-		if cipherSuite.id == id {
-			return cipherSuite
-		}
-	}
-	return nil
-}
-
-// A list of cipher suite IDs that are, or have been, implemented by this
-// package.
-//
-// See https://www.iana.org/assignments/tls-parameters/tls-parameters.xml
-const (
-	// TLS 1.0 - 1.2 cipher suites.
-	TLS_RSA_WITH_RC4_128_SHA                      uint16 = 0x0005
-	TLS_RSA_WITH_3DES_EDE_CBC_SHA                 uint16 = 0x000a
-	TLS_RSA_WITH_AES_128_CBC_SHA                  uint16 = 0x002f
-	TLS_RSA_WITH_AES_256_CBC_SHA                  uint16 = 0x0035
-	TLS_RSA_WITH_AES_128_CBC_SHA256               uint16 = 0x003c
-	TLS_RSA_WITH_AES_128_GCM_SHA256               uint16 = 0x009c
-	TLS_RSA_WITH_AES_256_GCM_SHA384               uint16 = 0x009d
-	TLS_ECDHE_ECDSA_WITH_RC4_128_SHA              uint16 = 0xc007
-	TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA          uint16 = 0xc009
-	TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA          uint16 = 0xc00a
-	TLS_ECDHE_RSA_WITH_RC4_128_SHA                uint16 = 0xc011
-	TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA           uint16 = 0xc012
-	TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA            uint16 = 0xc013
-	TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA            uint16 = 0xc014
-	TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256       uint16 = 0xc023
-	TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256         uint16 = 0xc027
-	TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256         uint16 = 0xc02f
-	TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256       uint16 = 0xc02b
-	TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384         uint16 = 0xc030
-	TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384       uint16 = 0xc02c
-	TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256   uint16 = 0xcca8
-	TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xcca9
-
-	// TLS 1.3 cipher suites.
-	TLS_AES_128_GCM_SHA256       uint16 = 0x1301
-	TLS_AES_256_GCM_SHA384       uint16 = 0x1302
-	TLS_CHACHA20_POLY1305_SHA256 uint16 = 0x1303
-
-	// TLS_FALLBACK_SCSV isn't a standard cipher suite but an indicator
-	// that the client is doing version fallback. See RFC 7507.
-	TLS_FALLBACK_SCSV uint16 = 0x5600
-
-	// Legacy names for the corresponding cipher suites with the correct _SHA256
-	// suffix, retained for backward compatibility.
-	TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305   = TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
-	TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 = TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
-)

+ 0 - 1668
transport/cloudflaretls/common.go

@@ -1,1668 +0,0 @@
-// Copyright 2009 The Go Authors. 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 (
-	"bytes"
-	"container/list"
-	"context"
-	"crypto"
-	"crypto/ecdsa"
-	"crypto/ed25519"
-	"crypto/elliptic"
-	"crypto/rand"
-	"crypto/rsa"
-	"crypto/sha512"
-	"crypto/x509"
-	"errors"
-	"fmt"
-	"io"
-	"net"
-	"strings"
-	"sync"
-	"time"
-)
-
-const (
-	VersionTLS10 = 0x0301
-	VersionTLS11 = 0x0302
-	VersionTLS12 = 0x0303
-	VersionTLS13 = 0x0304
-
-	// Deprecated: SSLv3 is cryptographically broken, and is no longer
-	// supported by this package. See golang.org/issue/32716.
-	VersionSSL30 = 0x0300
-)
-
-const (
-	maxPlaintext       = 16384        // maximum plaintext payload length
-	maxCiphertext      = 16384 + 2048 // maximum ciphertext payload length
-	maxCiphertextTLS13 = 16384 + 256  // maximum ciphertext length in TLS 1.3
-	recordHeaderLen    = 5            // record header length
-	maxHandshake       = 65536        // maximum handshake we support (protocol max is 16 MB)
-	maxUselessRecords  = 16           // maximum number of consecutive non-advancing records
-)
-
-// TLS record types.
-type recordType uint8
-
-const (
-	recordTypeChangeCipherSpec recordType = 20
-	recordTypeAlert            recordType = 21
-	recordTypeHandshake        recordType = 22
-	recordTypeApplicationData  recordType = 23
-)
-
-// TLS handshake message types.
-const (
-	typeHelloRequest        uint8 = 0
-	typeClientHello         uint8 = 1
-	typeServerHello         uint8 = 2
-	typeNewSessionTicket    uint8 = 4
-	typeEndOfEarlyData      uint8 = 5
-	typeEncryptedExtensions uint8 = 8
-	typeCertificate         uint8 = 11
-	typeServerKeyExchange   uint8 = 12
-	typeCertificateRequest  uint8 = 13
-	typeServerHelloDone     uint8 = 14
-	typeCertificateVerify   uint8 = 15
-	typeClientKeyExchange   uint8 = 16
-	typeFinished            uint8 = 20
-	typeCertificateStatus   uint8 = 22
-	typeKeyUpdate           uint8 = 24
-	typeNextProtocol        uint8 = 67  // Not IANA assigned
-	typeMessageHash         uint8 = 254 // synthetic message
-)
-
-// TLS compression types.
-const (
-	compressionNone uint8 = 0
-)
-
-// TLS extension numbers
-const (
-	extensionServerName              uint16 = 0
-	extensionStatusRequest           uint16 = 5
-	extensionSupportedCurves         uint16 = 10 // supported_groups in TLS 1.3, see RFC 8446, Section 4.2.7
-	extensionSupportedPoints         uint16 = 11
-	extensionSignatureAlgorithms     uint16 = 13
-	extensionALPN                    uint16 = 16
-	extensionSCT                     uint16 = 18
-	extensionDelegatedCredentials    uint16 = 34
-	extensionSessionTicket           uint16 = 35
-	extensionPreSharedKey            uint16 = 41
-	extensionEarlyData               uint16 = 42
-	extensionSupportedVersions       uint16 = 43
-	extensionCookie                  uint16 = 44
-	extensionPSKModes                uint16 = 45
-	extensionCertificateAuthorities  uint16 = 47
-	extensionSignatureAlgorithmsCert uint16 = 50
-	extensionKeyShare                uint16 = 51
-	extensionRenegotiationInfo       uint16 = 0xff01
-	extensionECH                     uint16 = 0xfe0d // draft-ietf-tls-esni-13
-	extensionECHOuterExtensions      uint16 = 0xfd00 // draft-ietf-tls-esni-13
-)
-
-// TLS signaling cipher suite values
-const (
-	scsvRenegotiation uint16 = 0x00ff
-)
-
-// CurveID is the type of a TLS identifier for an elliptic curve. See
-// https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-8.
-//
-// In TLS 1.3, this type is called NamedGroup, but at this time this library
-// only supports Elliptic Curve based groups. See RFC 8446, Section 4.2.7.
-type CurveID uint16
-
-const (
-	CurveP256 CurveID = 23
-	CurveP384 CurveID = 24
-	CurveP521 CurveID = 25
-	X25519    CurveID = 29
-)
-
-// TLS 1.3 Key Share. See RFC 8446, Section 4.2.8.
-type keyShare struct {
-	group CurveID
-	data  []byte
-}
-
-// TLS 1.3 PSK Key Exchange Modes. See RFC 8446, Section 4.2.9.
-const (
-	pskModePlain uint8 = 0
-	pskModeDHE   uint8 = 1
-)
-
-// TLS 1.3 PSK Identity. Can be a Session Ticket, or a reference to a saved
-// session. See RFC 8446, Section 4.2.11.
-type pskIdentity struct {
-	label               []byte
-	obfuscatedTicketAge uint32
-}
-
-// TLS Elliptic Curve Point Formats
-// https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-9
-const (
-	pointFormatUncompressed uint8 = 0
-)
-
-// TLS CertificateStatusType (RFC 3546)
-const (
-	statusTypeOCSP uint8 = 1
-)
-
-// Certificate types (for certificateRequestMsg)
-const (
-	certTypeRSASign   = 1
-	certTypeECDSASign = 64 // ECDSA or EdDSA keys, see RFC 8422, Section 3.
-)
-
-// Signature algorithms (for internal signaling use). Starting at 225 to avoid overlap with
-// TLS 1.2 codepoints (RFC 5246, Appendix A.4.1), with which these have nothing to do.
-const (
-	signaturePKCS1v15 uint8 = iota + 225
-	signatureRSAPSS
-	signatureECDSA
-	signatureEd25519
-	signatureEdDilithium3
-)
-
-// directSigning is a standard Hash value that signals that no pre-hashing
-// should be performed, and that the input should be signed directly. It is the
-// hash function associated with the Ed25519 signature scheme.
-var directSigning crypto.Hash = 0
-
-// supportedSignatureAlgorithms contains the signature and hash algorithms that
-// the code advertises as supported in a TLS 1.2+ ClientHello and in a TLS 1.2+
-// CertificateRequest. The two fields are merged to match with TLS 1.3.
-// Note that in TLS 1.2, the ECDSA algorithms are not constrained to P-256, etc.
-var supportedSignatureAlgorithms = []SignatureScheme{
-	PSSWithSHA256,
-	ECDSAWithP256AndSHA256,
-	Ed25519,
-	PSSWithSHA384,
-	PSSWithSHA512,
-	PKCS1WithSHA256,
-	PKCS1WithSHA384,
-	PKCS1WithSHA512,
-	ECDSAWithP384AndSHA384,
-	ECDSAWithP521AndSHA512,
-	PKCS1WithSHA1,
-	ECDSAWithSHA1,
-}
-
-// supportedSignatureAlgorithmsDC contains the signature and hash algorithms that
-// the code advertises as supported in a TLS 1.3 ClientHello and in a TLS 1.3
-// CertificateRequest. This excludes 'rsa_pss_rsae_' algorithms.
-var supportedSignatureAlgorithmsDC = []SignatureScheme{
-	ECDSAWithP256AndSHA256,
-	Ed25519,
-	ECDSAWithP384AndSHA384,
-	ECDSAWithP521AndSHA512,
-}
-
-// helloRetryRequestRandom is set as the Random value of a ServerHello
-// to signal that the message is actually a HelloRetryRequest.
-var helloRetryRequestRandom = []byte{ // See RFC 8446, Section 4.1.3.
-	0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 0x61, 0x11,
-	0xBE, 0x1D, 0x8C, 0x02, 0x1E, 0x65, 0xB8, 0x91,
-	0xC2, 0xA2, 0x11, 0x16, 0x7A, 0xBB, 0x8C, 0x5E,
-	0x07, 0x9E, 0x09, 0xE2, 0xC8, 0xA8, 0x33, 0x9C,
-}
-
-const (
-	// downgradeCanaryTLS12 or downgradeCanaryTLS11 is embedded in the server
-	// random as a downgrade protection if the server would be capable of
-	// negotiating a higher version. See RFC 8446, Section 4.1.3.
-	downgradeCanaryTLS12 = "DOWNGRD\x01"
-	downgradeCanaryTLS11 = "DOWNGRD\x00"
-)
-
-// testingOnlyForceDowngradeCanary is set in tests to force the server side to
-// include downgrade canaries even if it's using its highers supported version.
-var testingOnlyForceDowngradeCanary bool
-
-// testingTriggerHRR causes the server to intentionally trigger a
-// HelloRetryRequest (HRR). This is useful for testing new TLS features that
-// change the HRR codepath.
-var testingTriggerHRR bool
-
-// testingECHTriggerBypassAfterHRR causes the client to bypass ECH after HRR.
-// If available, the client will offer ECH in the first CH only.
-var testingECHTriggerBypassAfterHRR bool
-
-// testingECHTriggerBypassBeforeHRR causes the client to bypass ECH before HRR.
-// The client will offer ECH in the second CH only.
-var testingECHTriggerBypassBeforeHRR bool
-
-// testingECHIllegalHandleAfterHRR causes the client to illegally change the ECH
-// extension after HRR.
-var testingECHIllegalHandleAfterHRR bool
-
-// testingECHTriggerPayloadDecryptError causes the client to to send an
-// inauthentic payload.
-var testingECHTriggerPayloadDecryptError bool
-
-// testingECHOuterExtMany causes a client to incorporate a sequence of
-// outer extensions into the ClientHelloInner when it offers the ECH extension.
-// The "key_share" extension is the only incorporated extension by default.
-var testingECHOuterExtMany bool
-
-// testingECHOuterExtNone causes a client to not use the "outer_extension"
-// mechanism for ECH. The "key_shares" extension is incorporated by default.
-var testingECHOuterExtNone bool
-
-// testingECHOuterExtIncorrectOrder causes the client to send the
-// "outer_extension" extension in the wrong order when offering the ECH
-// extension.
-var testingECHOuterExtIncorrectOrder bool
-
-// testingECHOuterExtIllegal causes the client to send in its
-// "outer_extension" extension the codepoint for the ECH extension.
-var testingECHOuterExtIllegal bool
-
-// ConnectionState records basic TLS details about the connection.
-type ConnectionState struct {
-	// Version is the TLS version used by the connection (e.g. VersionTLS12).
-	Version uint16
-
-	// HandshakeComplete is true if the handshake has concluded.
-	HandshakeComplete bool
-
-	// DidResume is true if this connection was successfully resumed from a
-	// previous session with a session ticket or similar mechanism.
-	DidResume bool
-
-	// CipherSuite is the cipher suite negotiated for the connection (e.g.
-	// TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_AES_128_GCM_SHA256).
-	CipherSuite uint16
-
-	// NegotiatedProtocol is the application protocol negotiated with ALPN.
-	NegotiatedProtocol string
-
-	// NegotiatedProtocolIsMutual used to indicate a mutual NPN negotiation.
-	//
-	// Deprecated: this value is always true.
-	NegotiatedProtocolIsMutual bool
-
-	// ServerName is the value of the Server Name Indication extension sent by
-	// the client. It's available both on the server and on the client side.
-	ServerName string
-
-	// PeerCertificates are the parsed certificates sent by the peer, in the
-	// order in which they were sent. The first element is the leaf certificate
-	// that the connection is verified against.
-	//
-	// On the client side, it can't be empty. On the server side, it can be
-	// empty if Config.ClientAuth is not RequireAnyClientCert or
-	// RequireAndVerifyClientCert.
-	PeerCertificates []*x509.Certificate
-
-	// VerifiedChains is a list of one or more chains where the first element is
-	// PeerCertificates[0] and the last element is from Config.RootCAs (on the
-	// client side) or Config.ClientCAs (on the server side).
-	//
-	// On the client side, it's set if Config.InsecureSkipVerify is false. On
-	// the server side, it's set if Config.ClientAuth is VerifyClientCertIfGiven
-	// (and the peer provided a certificate) or RequireAndVerifyClientCert.
-	VerifiedChains [][]*x509.Certificate
-
-	// VerifiedDC indicates that the Delegated Credential sent by the peer (if advertised
-	// and correctly processed), which has been verified against the leaf certificate,
-	// has been used.
-	VerifiedDC bool
-
-	// SignedCertificateTimestamps is a list of SCTs provided by the peer
-	// through the TLS handshake for the leaf certificate, if any.
-	SignedCertificateTimestamps [][]byte
-
-	// OCSPResponse is a stapled Online Certificate Status Protocol (OCSP)
-	// response provided by the peer for the leaf certificate, if any.
-	OCSPResponse []byte
-
-	// TLSUnique contains the "tls-unique" channel binding value (see RFC 5929,
-	// Section 3). This value will be nil for TLS 1.3 connections and for all
-	// resumed connections.
-	//
-	// Deprecated: there are conditions in which this value might not be unique
-	// to a connection. See the Security Considerations sections of RFC 5705 and
-	// RFC 7627, and https://mitls.org/pages/attacks/3SHAKE#channelbindings.
-	TLSUnique []byte
-
-	// ECHAccepted is set if the ECH extension was offered by the client and
-	// accepted by the server.
-	ECHAccepted bool
-
-	// ECHOffered is set if the ECH extension is present in the ClientHello.
-	// This means the client has offered ECH or sent GREASE ECH.
-	ECHOffered bool
-
-	// CFControl is used to pass additional TLS configuration information to
-	// HTTP requests.
-	//
-	// NOTE: This feature is used to implement Cloudflare-internal features.
-	// This feature is unstable and applications MUST NOT depend on it.
-	CFControl interface{}
-
-	// ekm is a closure exposed via ExportKeyingMaterial.
-	ekm func(label string, context []byte, length int) ([]byte, error)
-}
-
-// ExportKeyingMaterial returns length bytes of exported key material in a new
-// slice as defined in RFC 5705. If context is nil, it is not used as part of
-// the seed. If the connection was set to allow renegotiation via
-// Config.Renegotiation, this function will return an error.
-func (cs *ConnectionState) ExportKeyingMaterial(label string, context []byte, length int) ([]byte, error) {
-	return cs.ekm(label, context, length)
-}
-
-// ClientAuthType declares the policy the server will follow for
-// TLS Client Authentication.
-type ClientAuthType int
-
-const (
-	// NoClientCert indicates that no client certificate should be requested
-	// during the handshake, and if any certificates are sent they will not
-	// be verified.
-	NoClientCert ClientAuthType = iota
-	// RequestClientCert indicates that a client certificate should be requested
-	// during the handshake, but does not require that the client send any
-	// certificates.
-	RequestClientCert
-	// RequireAnyClientCert indicates that a client certificate should be requested
-	// during the handshake, and that at least one certificate is required to be
-	// sent by the client, but that certificate is not required to be valid.
-	RequireAnyClientCert
-	// VerifyClientCertIfGiven indicates that a client certificate should be requested
-	// during the handshake, but does not require that the client sends a
-	// certificate. If the client does send a certificate it is required to be
-	// valid.
-	VerifyClientCertIfGiven
-	// RequireAndVerifyClientCert indicates that a client certificate should be requested
-	// during the handshake, and that at least one valid certificate is required
-	// to be sent by the client.
-	RequireAndVerifyClientCert
-)
-
-// requiresClientCert reports whether the ClientAuthType requires a client
-// certificate to be provided.
-func requiresClientCert(c ClientAuthType) bool {
-	switch c {
-	case RequireAnyClientCert, RequireAndVerifyClientCert:
-		return true
-	default:
-		return false
-	}
-}
-
-// ClientSessionState contains the state needed by clients to resume TLS
-// sessions.
-type ClientSessionState struct {
-	sessionTicket      []uint8               // Encrypted ticket used for session resumption with server
-	vers               uint16                // TLS version negotiated for the session
-	cipherSuite        uint16                // Ciphersuite negotiated for the session
-	masterSecret       []byte                // Full handshake MasterSecret, or TLS 1.3 resumption_master_secret
-	serverCertificates []*x509.Certificate   // Certificate chain presented by the server
-	verifiedChains     [][]*x509.Certificate // Certificate chains we built for verification
-	receivedAt         time.Time             // When the session ticket was received from the server
-	ocspResponse       []byte                // Stapled OCSP response presented by the server
-	scts               [][]byte              // SCTs presented by the server
-
-	// TLS 1.3 fields.
-	nonce  []byte    // Ticket nonce sent by the server, to derive PSK
-	useBy  time.Time // Expiration of the ticket lifetime as set by the server
-	ageAdd uint32    // Random obfuscation factor for sending the ticket age
-}
-
-// ClientSessionCache is a cache of ClientSessionState objects that can be used
-// by a client to resume a TLS session with a given server. ClientSessionCache
-// implementations should expect to be called concurrently from different
-// goroutines. Up to TLS 1.2, only ticket-based resumption is supported, not
-// SessionID-based resumption. In TLS 1.3 they were merged into PSK modes, which
-// are supported via this interface.
-type ClientSessionCache interface {
-	// Get searches for a ClientSessionState associated with the given key.
-	// On return, ok is true if one was found.
-	Get(sessionKey string) (session *ClientSessionState, ok bool)
-
-	// Put adds the ClientSessionState to the cache with the given key. It might
-	// get called multiple times in a connection if a TLS 1.3 server provides
-	// more than one session ticket. If called with a nil *ClientSessionState,
-	// it should remove the cache entry.
-	Put(sessionKey string, cs *ClientSessionState)
-}
-
-//go:generate stringer -type=SignatureScheme,CurveID,ClientAuthType -output=common_string.go
-
-// SignatureScheme identifies a signature algorithm supported by TLS. See
-// RFC 8446, Section 4.2.3.
-type SignatureScheme uint16
-
-const (
-	// RSASSA-PKCS1-v1_5 algorithms.
-	PKCS1WithSHA256 SignatureScheme = 0x0401
-	PKCS1WithSHA384 SignatureScheme = 0x0501
-	PKCS1WithSHA512 SignatureScheme = 0x0601
-
-	// RSASSA-PSS algorithms with public key OID rsaEncryption.
-	PSSWithSHA256 SignatureScheme = 0x0804
-	PSSWithSHA384 SignatureScheme = 0x0805
-	PSSWithSHA512 SignatureScheme = 0x0806
-
-	// ECDSA algorithms. Only constrained to a specific curve in TLS 1.3.
-	ECDSAWithP256AndSHA256 SignatureScheme = 0x0403
-	ECDSAWithP384AndSHA384 SignatureScheme = 0x0503
-	ECDSAWithP521AndSHA512 SignatureScheme = 0x0603
-
-	// EdDSA algorithms.
-	Ed25519 SignatureScheme = 0x0807
-
-	// Legacy signature and hash algorithms for TLS 1.2.
-	PKCS1WithSHA1 SignatureScheme = 0x0201
-	ECDSAWithSHA1 SignatureScheme = 0x0203
-)
-
-// ClientHelloInfo contains information from a ClientHello message in order to
-// guide application logic in the GetCertificate and GetConfigForClient callbacks.
-type ClientHelloInfo struct {
-	// CipherSuites lists the CipherSuites supported by the client (e.g.
-	// TLS_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256).
-	CipherSuites []uint16
-
-	// ServerName indicates the name of the server requested by the client
-	// in order to support virtual hosting. ServerName is only set if the
-	// client is using SNI (see RFC 4366, Section 3.1).
-	ServerName string
-
-	// SupportedCurves lists the elliptic curves supported by the client.
-	// SupportedCurves is set only if the Supported Elliptic Curves
-	// Extension is being used (see RFC 4492, Section 5.1.1).
-	SupportedCurves []CurveID
-
-	// SupportedPoints lists the point formats supported by the client.
-	// SupportedPoints is set only if the Supported Point Formats Extension
-	// is being used (see RFC 4492, Section 5.1.2).
-	SupportedPoints []uint8
-
-	// SignatureSchemes lists the signature and hash schemes that the client
-	// is willing to verify. SignatureSchemes is set only if the Signature
-	// Algorithms Extension is being used (see RFC 5246, Section 7.4.1.4.1).
-	SignatureSchemes []SignatureScheme
-
-	// SignatureSchemesDC lists the signature schemes that the client
-	// is willing to verify when using Delegated Credentials.
-	// This is and can be different from SignatureSchemes. SignatureSchemesDC
-	// is set only if the DelegatedCredentials Extension is being used.
-	// If Delegated Credentials are supported, this list should not be nil.
-	SignatureSchemesDC []SignatureScheme
-
-	// SupportedProtos lists the application protocols supported by the client.
-	// SupportedProtos is set only if the Application-Layer Protocol
-	// Negotiation Extension is being used (see RFC 7301, Section 3.1).
-	//
-	// Servers can select a protocol by setting Config.NextProtos in a
-	// GetConfigForClient return value.
-	SupportedProtos []string
-
-	// SupportedVersions lists the TLS versions supported by the client.
-	// For TLS versions less than 1.3, this is extrapolated from the max
-	// version advertised by the client, so values other than the greatest
-	// might be rejected if used.
-	SupportedVersions []uint16
-
-	// SupportDelegatedCredential is true if the client indicated willingness
-	// to negotiate the Delegated Credential extension.
-	SupportsDelegatedCredential bool
-
-	// Conn is the underlying net.Conn for the connection. Do not read
-	// from, or write to, this connection; that will cause the TLS
-	// connection to fail.
-	Conn net.Conn
-
-	// config is embedded by the GetCertificate or GetConfigForClient caller,
-	// for use with SupportsCertificate.
-	config *Config
-
-	// ctx is the context of the handshake that is in progress.
-	ctx context.Context
-}
-
-// Context returns the context of the handshake that is in progress.
-// This context is a child of the context passed to HandshakeContext,
-// if any, and is canceled when the handshake concludes.
-func (c *ClientHelloInfo) Context() context.Context {
-	return c.ctx
-}
-
-// CertificateRequestInfo contains information from a server's
-// CertificateRequest message, which is used to demand a certificate and proof
-// of control from a client.
-type CertificateRequestInfo struct {
-	// AcceptableCAs contains zero or more, DER-encoded, X.501
-	// Distinguished Names. These are the names of root or intermediate CAs
-	// that the server wishes the returned certificate to be signed by. An
-	// empty slice indicates that the server has no preference.
-	AcceptableCAs [][]byte
-
-	// SupportDelegatedCredential is true if the server indicated willingness
-	// to negotiate the Delegated Credential extension.
-	SupportsDelegatedCredential bool
-
-	// SignatureSchemes lists the signature schemes that the server is
-	// willing to verify.
-	SignatureSchemes []SignatureScheme
-
-	// SignatureSchemesDC lists the signature schemes that the server
-	// is willing to verify when using Delegated Credentials.
-	// This is and can be different from SignatureSchemes. SignatureSchemesDC
-	// is set only if the DelegatedCredentials Extension is being used.
-	// If Delegated Credentials are supported, this list should not be nil.
-	SignatureSchemesDC []SignatureScheme
-
-	// Version is the TLS version that was negotiated for this connection.
-	Version uint16
-
-	// ctx is the context of the handshake that is in progress.
-	ctx context.Context
-}
-
-// Context returns the context of the handshake that is in progress.
-// This context is a child of the context passed to HandshakeContext,
-// if any, and is canceled when the handshake concludes.
-func (c *CertificateRequestInfo) Context() context.Context {
-	return c.ctx
-}
-
-// RenegotiationSupport enumerates the different levels of support for TLS
-// renegotiation. TLS renegotiation is the act of performing subsequent
-// handshakes on a connection after the first. This significantly complicates
-// the state machine and has been the source of numerous, subtle security
-// issues. Initiating a renegotiation is not supported, but support for
-// accepting renegotiation requests may be enabled.
-//
-// Even when enabled, the server may not change its identity between handshakes
-// (i.e. the leaf certificate must be the same). Additionally, concurrent
-// handshake and application data flow is not permitted so renegotiation can
-// only be used with protocols that synchronise with the renegotiation, such as
-// HTTPS.
-//
-// Renegotiation is not defined in TLS 1.3.
-type RenegotiationSupport int
-
-const (
-	// RenegotiateNever disables renegotiation.
-	RenegotiateNever RenegotiationSupport = iota
-
-	// RenegotiateOnceAsClient allows a remote server to request
-	// renegotiation once per connection.
-	RenegotiateOnceAsClient
-
-	// RenegotiateFreelyAsClient allows a remote server to repeatedly
-	// request renegotiation.
-	RenegotiateFreelyAsClient
-)
-
-// A Config structure is used to configure a TLS client or server.
-// After one has been passed to a TLS function it must not be
-// modified. A Config may be reused; the tls package will also not
-// modify it.
-type Config struct {
-	// Rand provides the source of entropy for nonces and RSA blinding.
-	// If Rand is nil, TLS uses the cryptographic random reader in package
-	// crypto/rand.
-	// The Reader must be safe for use by multiple goroutines.
-	Rand io.Reader
-
-	// Time returns the current time as the number of seconds since the epoch.
-	// If Time is nil, TLS uses time.Now.
-	Time func() time.Time
-
-	// Certificates contains one or more certificate chains to present to the
-	// other side of the connection. The first certificate compatible with the
-	// peer's requirements is selected automatically.
-	//
-	// Server configurations must set one of Certificates, GetCertificate or
-	// GetConfigForClient. Clients doing client-authentication may set either
-	// Certificates or GetClientCertificate.
-	//
-	// Note: if there are multiple Certificates, and they don't have the
-	// optional field Leaf set, certificate selection will incur a significant
-	// per-handshake performance cost.
-	Certificates []Certificate
-
-	// NameToCertificate maps from a certificate name to an element of
-	// Certificates. Note that a certificate name can be of the form
-	// '*.example.com' and so doesn't have to be a domain name as such.
-	//
-	// Deprecated: NameToCertificate only allows associating a single
-	// certificate with a given name. Leave this field nil to let the library
-	// select the first compatible chain from Certificates.
-	NameToCertificate map[string]*Certificate
-
-	// GetCertificate returns a Certificate based on the given
-	// ClientHelloInfo. It will only be called if the client supplies SNI
-	// information or if Certificates is empty.
-	//
-	// If GetCertificate is nil or returns nil, then the certificate is
-	// retrieved from NameToCertificate. If NameToCertificate is nil, the
-	// best element of Certificates will be used.
-	GetCertificate func(*ClientHelloInfo) (*Certificate, error)
-
-	// GetClientCertificate, if not nil, is called when a server requests a
-	// certificate from a client. If set, the contents of Certificates will
-	// be ignored.
-	//
-	// If GetClientCertificate returns an error, the handshake will be
-	// aborted and that error will be returned. Otherwise
-	// GetClientCertificate must return a non-nil Certificate. If
-	// Certificate.Certificate is empty then no certificate will be sent to
-	// the server. If this is unacceptable to the server then it may abort
-	// the handshake.
-	//
-	// GetClientCertificate may be called multiple times for the same
-	// connection if renegotiation occurs or if TLS 1.3 is in use.
-	GetClientCertificate func(*CertificateRequestInfo) (*Certificate, error)
-
-	// GetConfigForClient, if not nil, is called after a ClientHello is
-	// received from a client. It may return a non-nil Config in order to
-	// change the Config that will be used to handle this connection. If
-	// the returned Config is nil, the original Config will be used. The
-	// Config returned by this callback may not be subsequently modified.
-	//
-	// If GetConfigForClient is nil, the Config passed to Server() will be
-	// used for all connections.
-	//
-	// If SessionTicketKey was explicitly set on the returned Config, or if
-	// SetSessionTicketKeys was called on the returned Config, those keys will
-	// be used. Otherwise, the original Config keys will be used (and possibly
-	// rotated if they are automatically managed).
-	GetConfigForClient func(*ClientHelloInfo) (*Config, error)
-
-	// VerifyPeerCertificate, if not nil, is called after normal
-	// certificate verification by either a TLS client or server. It
-	// receives the raw ASN.1 certificates provided by the peer and also
-	// any verified chains that normal processing found. If it returns a
-	// non-nil error, the handshake is aborted and that error results.
-	//
-	// If normal verification fails then the handshake will abort before
-	// considering this callback. If normal verification is disabled by
-	// setting InsecureSkipVerify, or (for a server) when ClientAuth is
-	// RequestClientCert or RequireAnyClientCert, then this callback will
-	// be considered but the verifiedChains argument will always be nil.
-	VerifyPeerCertificate func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error
-
-	// VerifyConnection, if not nil, is called after normal certificate
-	// verification and after VerifyPeerCertificate by either a TLS client
-	// or server. If it returns a non-nil error, the handshake is aborted
-	// and that error results.
-	//
-	// If normal verification fails then the handshake will abort before
-	// considering this callback. This callback will run for all connections
-	// regardless of InsecureSkipVerify or ClientAuth settings.
-	VerifyConnection func(ConnectionState) error
-
-	// RootCAs defines the set of root certificate authorities
-	// that clients use when verifying server certificates.
-	// If RootCAs is nil, TLS uses the host's root CA set.
-	RootCAs *x509.CertPool
-
-	// NextProtos is a list of supported application level protocols, in
-	// order of preference. If both peers support ALPN, the selected
-	// protocol will be one from this list, and the connection will fail
-	// if there is no mutually supported protocol. If NextProtos is empty
-	// or the peer doesn't support ALPN, the connection will succeed and
-	// ConnectionState.NegotiatedProtocol will be empty.
-	NextProtos []string
-
-	// ServerName is used to verify the hostname on the returned
-	// certificates unless InsecureSkipVerify is given. It is also included
-	// in the client's handshake to support virtual hosting unless it is
-	// an IP address.
-	ServerName string
-
-	// ClientAuth determines the server's policy for
-	// TLS Client Authentication. The default is NoClientCert.
-	ClientAuth ClientAuthType
-
-	// ClientCAs defines the set of root certificate authorities
-	// that servers use if required to verify a client certificate
-	// by the policy in ClientAuth.
-	ClientCAs *x509.CertPool
-
-	// InsecureSkipVerify controls whether a client verifies the server's
-	// certificate chain and host name. If InsecureSkipVerify is true, crypto/tls
-	// accepts any certificate presented by the server and any host name in that
-	// certificate. In this mode, TLS is susceptible to machine-in-the-middle
-	// attacks unless custom verification is used. This should be used only for
-	// testing or in combination with VerifyConnection or VerifyPeerCertificate.
-	InsecureSkipVerify bool
-
-	// CipherSuites is a list of enabled TLS 1.0–1.2 cipher suites. The order of
-	// the list is ignored. Note that TLS 1.3 ciphersuites are not configurable.
-	//
-	// If CipherSuites is nil, a safe default list is used. The default cipher
-	// suites might change over time.
-	CipherSuites []uint16
-
-	// PreferServerCipherSuites is a legacy field and has no effect.
-	//
-	// It used to control whether the server would follow the client's or the
-	// server's preference. Servers now select the best mutually supported
-	// cipher suite based on logic that takes into account inferred client
-	// hardware, server hardware, and security.
-	//
-	// Deprecated: PreferServerCipherSuites is ignored.
-	PreferServerCipherSuites bool
-
-	// SessionTicketsDisabled may be set to true to disable session ticket and
-	// PSK (resumption) support. Note that on clients, session ticket support is
-	// also disabled if ClientSessionCache is nil. On clients or servers,
-	// support is disabled if the ECH extension is enabled.
-	SessionTicketsDisabled bool
-
-	// SessionTicketKey is used by TLS servers to provide session resumption.
-	// See RFC 5077 and the PSK mode of RFC 8446. If zero, it will be filled
-	// with random data before the first server handshake.
-	//
-	// Deprecated: if this field is left at zero, session ticket keys will be
-	// automatically rotated every day and dropped after seven days. For
-	// customizing the rotation schedule or synchronizing servers that are
-	// terminating connections for the same host, use SetSessionTicketKeys.
-	SessionTicketKey [32]byte
-
-	// ClientSessionCache is a cache of ClientSessionState entries for TLS
-	// session resumption. It is only used by clients.
-	ClientSessionCache ClientSessionCache
-
-	// MinVersion contains the minimum TLS version that is acceptable.
-	//
-	// By default, TLS 1.2 is currently used as the minimum when acting as a
-	// client, and TLS 1.0 when acting as a server. TLS 1.0 is the minimum
-	// supported by this package, both as a client and as a server.
-	//
-	// The client-side default can temporarily be reverted to TLS 1.0 by
-	// including the value "x509sha1=1" in the GODEBUG environment variable.
-	// Note that this option will be removed in Go 1.19 (but it will still be
-	// possible to set this field to VersionTLS10 explicitly).
-	MinVersion uint16
-
-	// MaxVersion contains the maximum TLS version that is acceptable.
-	//
-	// By default, the maximum version supported by this package is used,
-	// which is currently TLS 1.3.
-	MaxVersion uint16
-
-	// CurvePreferences contains the elliptic curves that will be used in
-	// an ECDHE handshake, in preference order. If empty, the default will
-	// be used. The client will use the first preference as the type for
-	// its key share in TLS 1.3. This may change in the future.
-	CurvePreferences []CurveID
-
-	// PQSignatureSchemesEnabled controls whether additional post-quantum
-	// signature schemes are supported for peer certificates. For available
-	// signature schemes, see tls_cf.go.
-	PQSignatureSchemesEnabled bool
-
-	// DynamicRecordSizingDisabled disables adaptive sizing of TLS records.
-	// When true, the largest possible TLS record size is always used. When
-	// false, the size of TLS records may be adjusted in an attempt to
-	// improve latency.
-	DynamicRecordSizingDisabled bool
-
-	// Renegotiation controls what types of renegotiation are supported.
-	// The default, none, is correct for the vast majority of applications.
-	Renegotiation RenegotiationSupport
-
-	// KeyLogWriter optionally specifies a destination for TLS master secrets
-	// in NSS key log format that can be used to allow external programs
-	// such as Wireshark to decrypt TLS connections.
-	// See https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format.
-	// Use of KeyLogWriter compromises security and should only be
-	// used for debugging.
-	KeyLogWriter io.Writer
-
-	// ECHEnabled determines whether the ECH extension is enabled for this
-	// connection.
-	ECHEnabled bool
-
-	// ClientECHConfigs are the parameters used by the client when it offers the
-	// ECH extension. If ECH is enabled, a suitable configuration is found, and
-	// the client supports TLS 1.3, then it will offer ECH in this handshake.
-	// Otherwise, if ECH is enabled, it will send a dummy ECH extension.
-	ClientECHConfigs []ECHConfig
-
-	GetClientECHConfigs func(ctx context.Context, serverName string) ([]ECHConfig, error)
-
-	// ServerECHProvider is the ECH provider used by the client-facing server
-	// for the ECH extension. If the client offers ECH and TLS 1.3 is
-	// negotiated, then the provider is used to compute the HPKE context
-	// (draft-irtf-cfrg-hpke-07), which in turn is used to decrypt the extension
-	// payload.
-	ServerECHProvider ECHProvider
-
-	// CFEventHandler, if set, is called by the client and server at various
-	// points during the handshake to handle specific events. This is used
-	// primarily for collecting metrics.
-	//
-	// NOTE: This feature is used to implement Cloudflare-internal features.
-	// This feature is unstable and applications MUST NOT depend on it.
-	CFEventHandler func(event CFEvent)
-
-	// CFControl is used to pass additional TLS configuration information to
-	// HTTP requests via ConnectionState.
-	//
-	// NOTE: This feature is used to implement Cloudflare-internal features.
-	// This feature is unstable and applications MUST NOT depend on it.
-	CFControl interface{}
-
-	// SupportDelegatedCredential is true if the client or server is willing
-	// to negotiate the delegated credential extension.
-	// This can only be used with TLS 1.3.
-	//
-	// See https://tools.ietf.org/html/draft-ietf-tls-subcerts.
-	SupportDelegatedCredential bool
-
-	// mutex protects sessionTicketKeys and autoSessionTicketKeys.
-	mutex sync.RWMutex
-	// sessionTicketKeys contains zero or more ticket keys. If set, it means the
-	// the keys were set with SessionTicketKey or SetSessionTicketKeys. The
-	// first key is used for new tickets and any subsequent keys can be used to
-	// decrypt old tickets. The slice contents are not protected by the mutex
-	// and are immutable.
-	sessionTicketKeys []ticketKey
-	// autoSessionTicketKeys is like sessionTicketKeys but is owned by the
-	// auto-rotation logic. See Config.ticketKeys.
-	autoSessionTicketKeys []ticketKey
-}
-
-const (
-	// ticketKeyNameLen is the number of bytes of identifier that is prepended to
-	// an encrypted session ticket in order to identify the key used to encrypt it.
-	ticketKeyNameLen = 16
-
-	// ticketKeyLifetime is how long a ticket key remains valid and can be used to
-	// resume a client connection.
-	ticketKeyLifetime = 7 * 24 * time.Hour // 7 days
-
-	// ticketKeyRotation is how often the server should rotate the session ticket key
-	// that is used for new tickets.
-	ticketKeyRotation = 24 * time.Hour
-)
-
-// ticketKey is the internal representation of a session ticket key.
-type ticketKey struct {
-	// keyName is an opaque byte string that serves to identify the session
-	// ticket key. It's exposed as plaintext in every session ticket.
-	keyName [ticketKeyNameLen]byte
-	aesKey  [16]byte
-	hmacKey [16]byte
-	// created is the time at which this ticket key was created. See Config.ticketKeys.
-	created time.Time
-}
-
-// ticketKeyFromBytes converts from the external representation of a session
-// ticket key to a ticketKey. Externally, session ticket keys are 32 random
-// bytes and this function expands that into sufficient name and key material.
-func (c *Config) ticketKeyFromBytes(b [32]byte) (key ticketKey) {
-	hashed := sha512.Sum512(b[:])
-	copy(key.keyName[:], hashed[:ticketKeyNameLen])
-	copy(key.aesKey[:], hashed[ticketKeyNameLen:ticketKeyNameLen+16])
-	copy(key.hmacKey[:], hashed[ticketKeyNameLen+16:ticketKeyNameLen+32])
-	key.created = c.time()
-	return key
-}
-
-// maxSessionTicketLifetime is the maximum allowed lifetime of a TLS 1.3 session
-// ticket, and the lifetime we set for tickets we send.
-const maxSessionTicketLifetime = 7 * 24 * time.Hour
-
-// Clone returns a shallow clone of c or nil if c is nil. It is safe to clone a Config that is
-// being used concurrently by a TLS client or server.
-func (c *Config) Clone() *Config {
-	if c == nil {
-		return nil
-	}
-	c.mutex.RLock()
-	defer c.mutex.RUnlock()
-	return &Config{
-		Rand:                        c.Rand,
-		Time:                        c.Time,
-		Certificates:                c.Certificates,
-		NameToCertificate:           c.NameToCertificate,
-		GetCertificate:              c.GetCertificate,
-		GetClientCertificate:        c.GetClientCertificate,
-		GetConfigForClient:          c.GetConfigForClient,
-		VerifyPeerCertificate:       c.VerifyPeerCertificate,
-		VerifyConnection:            c.VerifyConnection,
-		RootCAs:                     c.RootCAs,
-		NextProtos:                  c.NextProtos,
-		ServerName:                  c.ServerName,
-		ClientAuth:                  c.ClientAuth,
-		ClientCAs:                   c.ClientCAs,
-		InsecureSkipVerify:          c.InsecureSkipVerify,
-		CipherSuites:                c.CipherSuites,
-		PreferServerCipherSuites:    c.PreferServerCipherSuites,
-		SessionTicketsDisabled:      c.SessionTicketsDisabled,
-		SessionTicketKey:            c.SessionTicketKey,
-		ClientSessionCache:          c.ClientSessionCache,
-		MinVersion:                  c.MinVersion,
-		MaxVersion:                  c.MaxVersion,
-		CurvePreferences:            c.CurvePreferences,
-		PQSignatureSchemesEnabled:   c.PQSignatureSchemesEnabled,
-		DynamicRecordSizingDisabled: c.DynamicRecordSizingDisabled,
-		Renegotiation:               c.Renegotiation,
-		KeyLogWriter:                c.KeyLogWriter,
-		SupportDelegatedCredential:  c.SupportDelegatedCredential,
-		ECHEnabled:                  c.ECHEnabled,
-		ClientECHConfigs:            c.ClientECHConfigs,
-		ServerECHProvider:           c.ServerECHProvider,
-		CFEventHandler:              c.CFEventHandler,
-		CFControl:                   c.CFControl,
-		sessionTicketKeys:           c.sessionTicketKeys,
-		autoSessionTicketKeys:       c.autoSessionTicketKeys,
-	}
-}
-
-// deprecatedSessionTicketKey is set as the prefix of SessionTicketKey if it was
-// randomized for backwards compatibility but is not in use.
-var deprecatedSessionTicketKey = []byte("DEPRECATED")
-
-// initLegacySessionTicketKeyRLocked ensures the legacy SessionTicketKey field is
-// randomized if empty, and that sessionTicketKeys is populated from it otherwise.
-func (c *Config) initLegacySessionTicketKeyRLocked() {
-	// Don't write if SessionTicketKey is already defined as our deprecated string,
-	// or if it is defined by the user but sessionTicketKeys is already set.
-	if c.SessionTicketKey != [32]byte{} &&
-		(bytes.HasPrefix(c.SessionTicketKey[:], deprecatedSessionTicketKey) || len(c.sessionTicketKeys) > 0) {
-		return
-	}
-
-	// We need to write some data, so get an exclusive lock and re-check any conditions.
-	c.mutex.RUnlock()
-	defer c.mutex.RLock()
-	c.mutex.Lock()
-	defer c.mutex.Unlock()
-	if c.SessionTicketKey == [32]byte{} {
-		if _, err := io.ReadFull(c.rand(), c.SessionTicketKey[:]); err != nil {
-			panic(fmt.Sprintf("tls: unable to generate random session ticket key: %v", err))
-		}
-		// Write the deprecated prefix at the beginning so we know we created
-		// it. This key with the DEPRECATED prefix isn't used as an actual
-		// session ticket key, and is only randomized in case the application
-		// reuses it for some reason.
-		copy(c.SessionTicketKey[:], deprecatedSessionTicketKey)
-	} else if !bytes.HasPrefix(c.SessionTicketKey[:], deprecatedSessionTicketKey) && len(c.sessionTicketKeys) == 0 {
-		c.sessionTicketKeys = []ticketKey{c.ticketKeyFromBytes(c.SessionTicketKey)}
-	}
-}
-
-// ticketKeys returns the ticketKeys for this connection.
-// If configForClient has explicitly set keys, those will
-// be returned. Otherwise, the keys on c will be used and
-// may be rotated if auto-managed.
-// During rotation, any expired session ticket keys are deleted from
-// c.sessionTicketKeys. If the session ticket key that is currently
-// encrypting tickets (ie. the first ticketKey in c.sessionTicketKeys)
-// is not fresh, then a new session ticket key will be
-// created and prepended to c.sessionTicketKeys.
-func (c *Config) ticketKeys(configForClient *Config) []ticketKey {
-	// If the ConfigForClient callback returned a Config with explicitly set
-	// keys, use those, otherwise just use the original Config.
-	if configForClient != nil {
-		configForClient.mutex.RLock()
-		if configForClient.SessionTicketsDisabled {
-			return nil
-		}
-		configForClient.initLegacySessionTicketKeyRLocked()
-		if len(configForClient.sessionTicketKeys) != 0 {
-			ret := configForClient.sessionTicketKeys
-			configForClient.mutex.RUnlock()
-			return ret
-		}
-		configForClient.mutex.RUnlock()
-	}
-
-	c.mutex.RLock()
-	defer c.mutex.RUnlock()
-	if c.SessionTicketsDisabled {
-		return nil
-	}
-	c.initLegacySessionTicketKeyRLocked()
-	if len(c.sessionTicketKeys) != 0 {
-		return c.sessionTicketKeys
-	}
-	// Fast path for the common case where the key is fresh enough.
-	if len(c.autoSessionTicketKeys) > 0 && c.time().Sub(c.autoSessionTicketKeys[0].created) < ticketKeyRotation {
-		return c.autoSessionTicketKeys
-	}
-
-	// autoSessionTicketKeys are managed by auto-rotation.
-	c.mutex.RUnlock()
-	defer c.mutex.RLock()
-	c.mutex.Lock()
-	defer c.mutex.Unlock()
-	// Re-check the condition in case it changed since obtaining the new lock.
-	if len(c.autoSessionTicketKeys) == 0 || c.time().Sub(c.autoSessionTicketKeys[0].created) >= ticketKeyRotation {
-		var newKey [32]byte
-		if _, err := io.ReadFull(c.rand(), newKey[:]); err != nil {
-			panic(fmt.Sprintf("unable to generate random session ticket key: %v", err))
-		}
-		valid := make([]ticketKey, 0, len(c.autoSessionTicketKeys)+1)
-		valid = append(valid, c.ticketKeyFromBytes(newKey))
-		for _, k := range c.autoSessionTicketKeys {
-			// While rotating the current key, also remove any expired ones.
-			if c.time().Sub(k.created) < ticketKeyLifetime {
-				valid = append(valid, k)
-			}
-		}
-		c.autoSessionTicketKeys = valid
-	}
-	return c.autoSessionTicketKeys
-}
-
-// SetSessionTicketKeys updates the session ticket keys for a server.
-//
-// The first key will be used when creating new tickets, while all keys can be
-// used for decrypting tickets. It is safe to call this function while the
-// server is running in order to rotate the session ticket keys. The function
-// will panic if keys is empty.
-//
-// Calling this function will turn off automatic session ticket key rotation.
-//
-// If multiple servers are terminating connections for the same host they should
-// all have the same session ticket keys. If the session ticket keys leaks,
-// previously recorded and future TLS connections using those keys might be
-// compromised.
-func (c *Config) SetSessionTicketKeys(keys [][32]byte) {
-	if len(keys) == 0 {
-		panic("tls: keys must have at least one key")
-	}
-
-	newKeys := make([]ticketKey, len(keys))
-	for i, bytes := range keys {
-		newKeys[i] = c.ticketKeyFromBytes(bytes)
-	}
-
-	c.mutex.Lock()
-	c.sessionTicketKeys = newKeys
-	c.mutex.Unlock()
-}
-
-func (c *Config) rand() io.Reader {
-	r := c.Rand
-	if r == nil {
-		return rand.Reader
-	}
-	return r
-}
-
-func (c *Config) time() time.Time {
-	t := c.Time
-	if t == nil {
-		t = time.Now
-	}
-	return t()
-}
-
-func (c *Config) cipherSuites() []uint16 {
-	if c.CipherSuites != nil {
-		return c.CipherSuites
-	}
-	return defaultCipherSuites
-}
-
-var supportedVersions = []uint16{
-	VersionTLS13,
-	VersionTLS12,
-	VersionTLS11,
-	VersionTLS10,
-}
-
-// debugEnableTLS10 enables TLS 1.0. See issue 45428.
-var debugEnableTLS10 = false
-
-// roleClient and roleServer are meant to call supportedVersions and parents
-// with more readability at the callsite.
-const roleClient = true
-const roleServer = false
-
-func (c *Config) supportedVersions(isClient bool) []uint16 {
-	versions := make([]uint16, 0, len(supportedVersions))
-	for _, v := range supportedVersions {
-		if (c == nil || c.MinVersion == 0) && !debugEnableTLS10 &&
-			isClient && v < VersionTLS12 {
-			continue
-		}
-		if c != nil && c.MinVersion != 0 && v < c.MinVersion {
-			continue
-		}
-		if c != nil && c.MaxVersion != 0 && v > c.MaxVersion {
-			continue
-		}
-		versions = append(versions, v)
-	}
-	return versions
-}
-
-func (c *Config) supportedVersionsFromMin(isClient bool, minVersion uint16) []uint16 {
-	versions := make([]uint16, 0, len(supportedVersions))
-	for _, v := range supportedVersions {
-		if (c == nil || c.MinVersion == 0) && !debugEnableTLS10 &&
-			isClient && v < VersionTLS12 {
-			continue
-		}
-		if c != nil && c.MinVersion != 0 && v < c.MinVersion {
-			continue
-		}
-		if c != nil && c.MaxVersion != 0 && v > c.MaxVersion {
-			continue
-		}
-		if v < minVersion {
-			continue
-		}
-		versions = append(versions, v)
-	}
-	return versions
-}
-
-func (c *Config) maxSupportedVersion(isClient bool) uint16 {
-	supportedVersions := c.supportedVersions(isClient)
-	if len(supportedVersions) == 0 {
-		return 0
-	}
-	return supportedVersions[0]
-}
-
-// supportedVersionsFromMax returns a list of supported versions derived from a
-// legacy maximum version value. Note that only versions supported by this
-// library are returned. Any newer peer will use supportedVersions anyway.
-func supportedVersionsFromMax(maxVersion uint16) []uint16 {
-	versions := make([]uint16, 0, len(supportedVersions))
-	for _, v := range supportedVersions {
-		if v > maxVersion {
-			continue
-		}
-		versions = append(versions, v)
-	}
-	return versions
-}
-
-var defaultCurvePreferences = []CurveID{X25519, CurveP256, CurveP384, CurveP521}
-
-func (c *Config) curvePreferences() []CurveID {
-	if c == nil || len(c.CurvePreferences) == 0 {
-		return defaultCurvePreferences
-	}
-	return c.CurvePreferences
-}
-
-func (c *Config) supportsCurve(curve CurveID) bool {
-	for _, cc := range c.curvePreferences() {
-		if cc == curve {
-			return true
-		}
-	}
-	return false
-}
-
-// mutualVersion returns the protocol version to use given the advertised
-// versions of the peer. Priority is given to the peer preference order.
-func (c *Config) mutualVersion(isClient bool, peerVersions []uint16) (uint16, bool) {
-	supportedVersions := c.supportedVersions(isClient)
-	for _, peerVersion := range peerVersions {
-		for _, v := range supportedVersions {
-			if v == peerVersion {
-				return v, true
-			}
-		}
-	}
-	return 0, false
-}
-
-var errNoCertificates = errors.New("tls: no certificates configured")
-
-// getCertificate returns the best certificate for the given ClientHelloInfo,
-// defaulting to the first element of c.Certificates.
-func (c *Config) getCertificate(clientHello *ClientHelloInfo) (*Certificate, error) {
-	if c.GetCertificate != nil &&
-		(len(c.Certificates) == 0 || len(clientHello.ServerName) > 0) {
-		cert, err := c.GetCertificate(clientHello)
-		if cert != nil || err != nil {
-			return cert, err
-		}
-	}
-
-	if len(c.Certificates) == 0 {
-		return nil, errNoCertificates
-	}
-
-	if len(c.Certificates) == 1 {
-		// There's only one choice, so no point doing any work.
-		return &c.Certificates[0], nil
-	}
-
-	if c.NameToCertificate != nil {
-		name := strings.ToLower(clientHello.ServerName)
-		if cert, ok := c.NameToCertificate[name]; ok {
-			return cert, nil
-		}
-		if len(name) > 0 {
-			labels := strings.Split(name, ".")
-			labels[0] = "*"
-			wildcardName := strings.Join(labels, ".")
-			if cert, ok := c.NameToCertificate[wildcardName]; ok {
-				return cert, nil
-			}
-		}
-	}
-
-	for _, cert := range c.Certificates {
-		if err := clientHello.SupportsCertificate(&cert); err == nil {
-			return &cert, nil
-		}
-	}
-
-	// If nothing matches, return the first certificate.
-	return &c.Certificates[0], nil
-}
-
-// SupportsCertificate returns nil if the provided certificate is supported by
-// the client that sent the ClientHello. Otherwise, it returns an error
-// describing the reason for the incompatibility.
-//
-// If this ClientHelloInfo was passed to a GetConfigForClient or GetCertificate
-// callback, this method will take into account the associated Config. Note that
-// if GetConfigForClient returns a different Config, the change can't be
-// accounted for by this method.
-//
-// This function will call x509.ParseCertificate unless c.Leaf is set, which can
-// incur a significant performance cost.
-func (chi *ClientHelloInfo) SupportsCertificate(c *Certificate) error {
-	// Note we don't currently support certificate_authorities nor
-	// signature_algorithms_cert, and don't check the algorithms of the
-	// signatures on the chain (which anyway are a SHOULD, see RFC 8446,
-	// Section 4.4.2.2).
-
-	config := chi.config
-	if config == nil {
-		config = &Config{}
-	}
-	vers, ok := config.mutualVersion(roleServer, chi.SupportedVersions)
-	if !ok {
-		return errors.New("no mutually supported protocol versions")
-	}
-
-	// If the client specified the name they are trying to connect to, the
-	// certificate needs to be valid for it.
-	if chi.ServerName != "" {
-		x509Cert, err := c.leaf()
-		if err != nil {
-			return fmt.Errorf("failed to parse certificate: %w", err)
-		}
-		if err := x509Cert.VerifyHostname(chi.ServerName); err != nil {
-			return fmt.Errorf("certificate is not valid for requested server name: %w", err)
-		}
-	}
-
-	// supportsRSAFallback returns nil if the certificate and connection support
-	// the static RSA key exchange, and unsupported otherwise. The logic for
-	// supporting static RSA is completely disjoint from the logic for
-	// supporting signed key exchanges, so we just check it as a fallback.
-	supportsRSAFallback := func(unsupported error) error {
-		// TLS 1.3 dropped support for the static RSA key exchange.
-		if vers == VersionTLS13 {
-			return unsupported
-		}
-		// The static RSA key exchange works by decrypting a challenge with the
-		// RSA private key, not by signing, so check the PrivateKey implements
-		// crypto.Decrypter, like *rsa.PrivateKey does.
-		if priv, ok := c.PrivateKey.(crypto.Decrypter); ok {
-			if _, ok := priv.Public().(*rsa.PublicKey); !ok {
-				return unsupported
-			}
-		} else {
-			return unsupported
-		}
-		// Finally, there needs to be a mutual cipher suite that uses the static
-		// RSA key exchange instead of ECDHE.
-		rsaCipherSuite := selectCipherSuite(chi.CipherSuites, config.cipherSuites(), func(c *cipherSuite) bool {
-			if c.flags&suiteECDHE != 0 {
-				return false
-			}
-			if vers < VersionTLS12 && c.flags&suiteTLS12 != 0 {
-				return false
-			}
-			return true
-		})
-		if rsaCipherSuite == nil {
-			return unsupported
-		}
-		return nil
-	}
-
-	// If the client sent the signature_algorithms extension, ensure it supports
-	// schemes we can use with this certificate and TLS version.
-	if len(chi.SignatureSchemes) > 0 {
-		if _, err := selectSignatureScheme(vers, c, chi.SignatureSchemes); err != nil {
-			return supportsRSAFallback(err)
-		}
-	}
-
-	// In TLS 1.3 we are done because supported_groups is only relevant to the
-	// ECDHE computation, point format negotiation is removed, cipher suites are
-	// only relevant to the AEAD choice, and static RSA does not exist.
-	if vers == VersionTLS13 {
-		return nil
-	}
-
-	// The only signed key exchange we support is ECDHE.
-	if !supportsECDHE(config, chi.SupportedCurves, chi.SupportedPoints) {
-		return supportsRSAFallback(errors.New("client doesn't support ECDHE, can only use legacy RSA key exchange"))
-	}
-
-	var ecdsaCipherSuite bool
-	if priv, ok := c.PrivateKey.(crypto.Signer); ok {
-		switch pub := priv.Public().(type) {
-		case *ecdsa.PublicKey:
-			var curve CurveID
-			switch pub.Curve {
-			case elliptic.P256():
-				curve = CurveP256
-			case elliptic.P384():
-				curve = CurveP384
-			case elliptic.P521():
-				curve = CurveP521
-			default:
-				return supportsRSAFallback(unsupportedCertificateError(c))
-			}
-			var curveOk bool
-			for _, c := range chi.SupportedCurves {
-				if c == curve && config.supportsCurve(c) {
-					curveOk = true
-					break
-				}
-			}
-			if !curveOk {
-				return errors.New("client doesn't support certificate curve")
-			}
-			ecdsaCipherSuite = true
-		case ed25519.PublicKey:
-			if vers < VersionTLS12 || len(chi.SignatureSchemes) == 0 {
-				return errors.New("connection doesn't support Ed25519")
-			}
-			ecdsaCipherSuite = true
-		case *rsa.PublicKey:
-		default:
-			return supportsRSAFallback(unsupportedCertificateError(c))
-		}
-	} else {
-		return supportsRSAFallback(unsupportedCertificateError(c))
-	}
-
-	// Make sure that there is a mutually supported cipher suite that works with
-	// this certificate. Cipher suite selection will then apply the logic in
-	// reverse to pick it. See also serverHandshakeState.cipherSuiteOk.
-	cipherSuite := selectCipherSuite(chi.CipherSuites, config.cipherSuites(), func(c *cipherSuite) bool {
-		if c.flags&suiteECDHE == 0 {
-			return false
-		}
-		if c.flags&suiteECSign != 0 {
-			if !ecdsaCipherSuite {
-				return false
-			}
-		} else {
-			if ecdsaCipherSuite {
-				return false
-			}
-		}
-		if vers < VersionTLS12 && c.flags&suiteTLS12 != 0 {
-			return false
-		}
-		return true
-	})
-	if cipherSuite == nil {
-		return supportsRSAFallback(errors.New("client doesn't support any cipher suites compatible with the certificate"))
-	}
-
-	return nil
-}
-
-// SupportsCertificate returns nil if the provided certificate is supported by
-// the server that sent the CertificateRequest. Otherwise, it returns an error
-// describing the reason for the incompatibility.
-func (cri *CertificateRequestInfo) SupportsCertificate(c *Certificate) error {
-	if _, err := selectSignatureScheme(cri.Version, c, cri.SignatureSchemes); err != nil {
-		return err
-	}
-
-	if len(cri.AcceptableCAs) == 0 {
-		return nil
-	}
-
-	for j, cert := range c.Certificate {
-		x509Cert := c.Leaf
-		// Parse the certificate if this isn't the leaf node, or if
-		// chain.Leaf was nil.
-		if j != 0 || x509Cert == nil {
-			var err error
-			if x509Cert, err = x509.ParseCertificate(cert); err != nil {
-				return fmt.Errorf("failed to parse certificate #%d in the chain: %w", j, err)
-			}
-		}
-
-		for _, ca := range cri.AcceptableCAs {
-			if bytes.Equal(x509Cert.RawIssuer, ca) {
-				return nil
-			}
-		}
-	}
-	return errors.New("chain is not signed by an acceptable CA")
-}
-
-// BuildNameToCertificate parses c.Certificates and builds c.NameToCertificate
-// from the CommonName and SubjectAlternateName fields of each of the leaf
-// certificates.
-//
-// Deprecated: NameToCertificate only allows associating a single certificate
-// with a given name. Leave that field nil to let the library select the first
-// compatible chain from Certificates.
-func (c *Config) BuildNameToCertificate() {
-	c.NameToCertificate = make(map[string]*Certificate)
-	for i := range c.Certificates {
-		cert := &c.Certificates[i]
-		x509Cert, err := cert.leaf()
-		if err != nil {
-			continue
-		}
-		// If SANs are *not* present, some clients will consider the certificate
-		// valid for the name in the Common Name.
-		if x509Cert.Subject.CommonName != "" && len(x509Cert.DNSNames) == 0 {
-			c.NameToCertificate[x509Cert.Subject.CommonName] = cert
-		}
-		for _, san := range x509Cert.DNSNames {
-			c.NameToCertificate[san] = cert
-		}
-	}
-}
-
-const (
-	keyLogLabelTLS12           = "CLIENT_RANDOM"
-	keyLogLabelClientHandshake = "CLIENT_HANDSHAKE_TRAFFIC_SECRET"
-	keyLogLabelServerHandshake = "SERVER_HANDSHAKE_TRAFFIC_SECRET"
-	keyLogLabelClientTraffic   = "CLIENT_TRAFFIC_SECRET_0"
-	keyLogLabelServerTraffic   = "SERVER_TRAFFIC_SECRET_0"
-)
-
-func (c *Config) writeKeyLog(label string, clientRandom, secret []byte) error {
-	if c.KeyLogWriter == nil {
-		return nil
-	}
-
-	logLine := []byte(fmt.Sprintf("%s %x %x\n", label, clientRandom, secret))
-
-	writerMutex.Lock()
-	_, err := c.KeyLogWriter.Write(logLine)
-	writerMutex.Unlock()
-
-	return err
-}
-
-// writerMutex protects all KeyLogWriters globally. It is rarely enabled,
-// and is only for debugging, so a global mutex saves space.
-var writerMutex sync.Mutex
-
-// A DelegatedCredentialPair contains a Delegated Credential and its
-// associated private key.
-type DelegatedCredentialPair struct {
-	// DC is the delegated credential.
-	DC *DelegatedCredential
-	// PrivateKey is the private key used to derive the public key of
-	// contained in DC. PrivateKey must implement crypto.Signer.
-	PrivateKey crypto.PrivateKey
-}
-
-// A Certificate is a chain of one or more certificates, leaf first.
-type Certificate struct {
-	Certificate [][]byte
-	// PrivateKey contains the private key corresponding to the public key in
-	// Leaf. This must implement crypto.Signer with an RSA, ECDSA or Ed25519 PublicKey.
-	// For a server up to TLS 1.2, it can also implement crypto.Decrypter with
-	// an RSA PublicKey.
-	PrivateKey crypto.PrivateKey
-	// SupportedSignatureAlgorithms is an optional list restricting what
-	// signature algorithms the PrivateKey can be used for.
-	SupportedSignatureAlgorithms []SignatureScheme
-	// OCSPStaple contains an optional OCSP response which will be served
-	// to clients that request it.
-	OCSPStaple []byte
-	// SignedCertificateTimestamps contains an optional list of Signed
-	// Certificate Timestamps which will be served to clients that request it.
-	SignedCertificateTimestamps [][]byte
-	// DelegatedCredentials are a list of Delegated Credentials with their
-	// corresponding private keys, signed by the leaf certificate.
-	// If there are no delegated credentials, this field is nil.
-	DelegatedCredentials []DelegatedCredentialPair
-	// DelegatedCredential is the delegated credential to be used in the
-	// handshake.
-	// If there are no delegated credentials, this field is nil.
-	// NOTE: Do not fill this field, as it will be filled depending on
-	// the provided list of delegated credentials.
-	DelegatedCredential []byte
-	// Leaf is the parsed form of the leaf certificate, which may be initialized
-	// using x509.ParseCertificate to reduce per-handshake processing. If nil,
-	// the leaf certificate will be parsed as needed.
-	Leaf *x509.Certificate
-}
-
-// leaf returns the parsed leaf certificate, either from c.Leaf or by parsing
-// the corresponding c.Certificate[0].
-func (c *Certificate) leaf() (*x509.Certificate, error) {
-	if c.Leaf != nil {
-		return c.Leaf, nil
-	}
-	return x509.ParseCertificate(c.Certificate[0])
-}
-
-type handshakeMessage interface {
-	marshal() []byte
-	unmarshal([]byte) bool
-}
-
-// lruSessionCache is a ClientSessionCache implementation that uses an LRU
-// caching strategy.
-type lruSessionCache struct {
-	sync.Mutex
-
-	m        map[string]*list.Element
-	q        *list.List
-	capacity int
-}
-
-type lruSessionCacheEntry struct {
-	sessionKey string
-	state      *ClientSessionState
-}
-
-// NewLRUClientSessionCache returns a ClientSessionCache with the given
-// capacity that uses an LRU strategy. If capacity is < 1, a default capacity
-// is used instead.
-func NewLRUClientSessionCache(capacity int) ClientSessionCache {
-	const defaultSessionCacheCapacity = 64
-
-	if capacity < 1 {
-		capacity = defaultSessionCacheCapacity
-	}
-	return &lruSessionCache{
-		m:        make(map[string]*list.Element),
-		q:        list.New(),
-		capacity: capacity,
-	}
-}
-
-// Put adds the provided (sessionKey, cs) pair to the cache. If cs is nil, the entry
-// corresponding to sessionKey is removed from the cache instead.
-func (c *lruSessionCache) Put(sessionKey string, cs *ClientSessionState) {
-	c.Lock()
-	defer c.Unlock()
-
-	if elem, ok := c.m[sessionKey]; ok {
-		if cs == nil {
-			c.q.Remove(elem)
-			delete(c.m, sessionKey)
-		} else {
-			entry := elem.Value.(*lruSessionCacheEntry)
-			entry.state = cs
-			c.q.MoveToFront(elem)
-		}
-		return
-	}
-
-	if c.q.Len() < c.capacity {
-		entry := &lruSessionCacheEntry{sessionKey, cs}
-		c.m[sessionKey] = c.q.PushFront(entry)
-		return
-	}
-
-	elem := c.q.Back()
-	entry := elem.Value.(*lruSessionCacheEntry)
-	delete(c.m, entry.sessionKey)
-	entry.sessionKey = sessionKey
-	entry.state = cs
-	c.q.MoveToFront(elem)
-	c.m[sessionKey] = elem
-}
-
-// Get returns the ClientSessionState value associated with a given key. It
-// returns (nil, false) if no value is found.
-func (c *lruSessionCache) Get(sessionKey string) (*ClientSessionState, bool) {
-	c.Lock()
-	defer c.Unlock()
-
-	if elem, ok := c.m[sessionKey]; ok {
-		c.q.MoveToFront(elem)
-		return elem.Value.(*lruSessionCacheEntry).state, true
-	}
-	return nil, false
-}
-
-var emptyConfig Config
-
-func defaultConfig() *Config {
-	return &emptyConfig
-}
-
-func unexpectedMessageError(wanted, got any) error {
-	return fmt.Errorf("tls: received unexpected handshake message of type %T when waiting for %T", got, wanted)
-}
-
-func isSupportedSignatureAlgorithm(sigAlg SignatureScheme, supportedSignatureAlgorithms []SignatureScheme) bool {
-	for _, s := range supportedSignatureAlgorithms {
-		if s == sigAlg {
-			return true
-		}
-	}
-	return false
-}

+ 0 - 116
transport/cloudflaretls/common_string.go

@@ -1,116 +0,0 @@
-// Code generated by "stringer -type=SignatureScheme,CurveID,ClientAuthType -output=common_string.go"; DO NOT EDIT.
-
-package tls
-
-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[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 (
-	_SignatureScheme_name_0 = "PKCS1WithSHA1"
-	_SignatureScheme_name_1 = "ECDSAWithSHA1"
-	_SignatureScheme_name_2 = "PKCS1WithSHA256"
-	_SignatureScheme_name_3 = "ECDSAWithP256AndSHA256"
-	_SignatureScheme_name_4 = "PKCS1WithSHA384"
-	_SignatureScheme_name_5 = "ECDSAWithP384AndSHA384"
-	_SignatureScheme_name_6 = "PKCS1WithSHA512"
-	_SignatureScheme_name_7 = "ECDSAWithP521AndSHA512"
-	_SignatureScheme_name_8 = "PSSWithSHA256PSSWithSHA384PSSWithSHA512Ed25519"
-)
-
-var (
-	_SignatureScheme_index_8 = [...]uint8{0, 13, 26, 39, 46}
-)
-
-func (i SignatureScheme) String() string {
-	switch {
-	case i == 513:
-		return _SignatureScheme_name_0
-	case i == 515:
-		return _SignatureScheme_name_1
-	case i == 1025:
-		return _SignatureScheme_name_2
-	case i == 1027:
-		return _SignatureScheme_name_3
-	case i == 1281:
-		return _SignatureScheme_name_4
-	case i == 1283:
-		return _SignatureScheme_name_5
-	case i == 1537:
-		return _SignatureScheme_name_6
-	case i == 1539:
-		return _SignatureScheme_name_7
-	case 2052 <= i && i <= 2055:
-		i -= 2052
-		return _SignatureScheme_name_8[_SignatureScheme_index_8[i]:_SignatureScheme_index_8[i+1]]
-	default:
-		return "SignatureScheme(" + 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[CurveP256-23]
-	_ = x[CurveP384-24]
-	_ = x[CurveP521-25]
-	_ = x[X25519-29]
-}
-
-const (
-	_CurveID_name_0 = "CurveP256CurveP384CurveP521"
-	_CurveID_name_1 = "X25519"
-)
-
-var (
-	_CurveID_index_0 = [...]uint8{0, 9, 18, 27}
-)
-
-func (i CurveID) String() string {
-	switch {
-	case 23 <= i && i <= 25:
-		i -= 23
-		return _CurveID_name_0[_CurveID_index_0[i]:_CurveID_index_0[i+1]]
-	case i == 29:
-		return _CurveID_name_1
-	default:
-		return "CurveID(" + 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[NoClientCert-0]
-	_ = x[RequestClientCert-1]
-	_ = x[RequireAnyClientCert-2]
-	_ = x[VerifyClientCertIfGiven-3]
-	_ = x[RequireAndVerifyClientCert-4]
-}
-
-const _ClientAuthType_name = "NoClientCertRequestClientCertRequireAnyClientCertVerifyClientCertIfGivenRequireAndVerifyClientCert"
-
-var _ClientAuthType_index = [...]uint8{0, 12, 29, 49, 72, 98}
-
-func (i ClientAuthType) String() string {
-	if i < 0 || i >= ClientAuthType(len(_ClientAuthType_index)-1) {
-		return "ClientAuthType(" + strconv.FormatInt(int64(i), 10) + ")"
-	}
-	return _ClientAuthType_name[_ClientAuthType_index[i]:_ClientAuthType_index[i+1]]
-}

+ 0 - 1603
transport/cloudflaretls/conn.go

@@ -1,1603 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// TLS low level connection and record layer
-
-package tls
-
-import (
-	"bytes"
-	"context"
-	"crypto/cipher"
-	"crypto/subtle"
-	"crypto/x509"
-	"errors"
-	"fmt"
-	"hash"
-	"io"
-	"net"
-	"sync"
-	"sync/atomic"
-	"time"
-
-	"github.com/cloudflare/circl/hpke"
-)
-
-// A Conn represents a secured connection.
-// It implements the net.Conn interface.
-type Conn struct {
-	// constant
-	conn        net.Conn
-	isClient    bool
-	handshakeFn func(context.Context) error // (*Conn).clientHandshake or serverHandshake
-
-	// handshakeStatus is 1 if the connection is currently transferring
-	// application data (i.e. is not currently processing a handshake).
-	// handshakeStatus == 1 implies handshakeErr == nil.
-	// This field is only to be accessed with sync/atomic.
-	handshakeStatus uint32
-	// constant after handshake; protected by handshakeMutex
-	handshakeMutex sync.Mutex
-	handshakeErr   error   // error resulting from handshake
-	vers           uint16  // TLS version
-	haveVers       bool    // version has been negotiated
-	config         *Config // configuration passed to constructor
-	// handshakes counts the number of handshakes performed on the
-	// connection so far. If renegotiation is disabled then this is either
-	// zero or one.
-	handshakes       int
-	didResume        bool // whether this connection was a session resumption
-	cipherSuite      uint16
-	ocspResponse     []byte   // stapled OCSP response
-	scts             [][]byte // signed certificate timestamps from server
-	peerCertificates []*x509.Certificate
-	// verifiedChains contains the certificate chains that we built, as
-	// opposed to the ones presented by the server.
-	verifiedChains [][]*x509.Certificate
-	// verifiedDC contains the Delegated Credential sent by the peer (if advertised
-	// and correctly processed), which has been verified against the leaf certificate.
-	verifiedDC *DelegatedCredential
-	// serverName contains the server name indicated by the client, if any.
-	serverName string
-	// secureRenegotiation is true if the server echoed the secure
-	// renegotiation extension. (This is meaningless as a server because
-	// renegotiation is not supported in that case.)
-	secureRenegotiation bool
-	// ekm is a closure for exporting keying material.
-	ekm func(label string, context []byte, length int) ([]byte, error)
-	// resumptionSecret is the resumption_master_secret for handling
-	// NewSessionTicket messages. nil if config.SessionTicketsDisabled.
-	resumptionSecret []byte
-
-	// ticketKeys is the set of active session ticket keys for this
-	// connection. The first one is used to encrypt new tickets and
-	// all are tried to decrypt tickets.
-	ticketKeys []ticketKey
-
-	// clientFinishedIsFirst is true if the client sent the first Finished
-	// message during the most recent handshake. This is recorded because
-	// the first transmitted Finished message is the tls-unique
-	// channel-binding value.
-	clientFinishedIsFirst bool
-
-	// closeNotifyErr is any error from sending the alertCloseNotify record.
-	closeNotifyErr error
-	// closeNotifySent is true if the Conn attempted to send an
-	// alertCloseNotify record.
-	closeNotifySent bool
-
-	// clientFinished and serverFinished contain the Finished message sent
-	// by the client or server in the most recent handshake. This is
-	// retained to support the renegotiation extension and tls-unique
-	// channel-binding.
-	clientFinished [12]byte
-	serverFinished [12]byte
-
-	// clientProtocol is the negotiated ALPN protocol.
-	clientProtocol string
-
-	// input/output
-	in, out   halfConn
-	rawInput  bytes.Buffer // raw input, starting with a record header
-	input     bytes.Reader // application data waiting to be read, from rawInput.Next
-	hand      bytes.Buffer // handshake data waiting to be read
-	buffering bool         // whether records are buffered in sendBuf
-	sendBuf   []byte       // a buffer of records waiting to be sent
-
-	// bytesSent counts the bytes of application data sent.
-	// packetsSent counts packets.
-	bytesSent   int64
-	packetsSent int64
-
-	// retryCount counts the number of consecutive non-advancing records
-	// received by Conn.readRecord. That is, records that neither advance the
-	// handshake, nor deliver application data. Protected by in.Mutex.
-	retryCount int
-
-	// activeCall is an atomic int32; the low bit is whether Close has
-	// been called. the rest of the bits are the number of goroutines
-	// in Conn.Write.
-	activeCall int32
-
-	tmp [16]byte
-
-	// State used for the ECH extension.
-	ech struct {
-		sealer hpke.Sealer // The client's HPKE context
-		opener hpke.Opener // The server's HPKE context
-
-		// The state shared by the client and server.
-		offered      bool   // Client offered ECH
-		greased      bool   // Client greased ECH
-		accepted     bool   // Server accepted ECH
-		retryConfigs []byte // The retry configurations
-		configId     uint8  // The ECH config id
-		maxNameLen   int    // maximum_name_len indicated by the ECH config
-	}
-}
-
-// Access to net.Conn methods.
-// Cannot just embed net.Conn because that would
-// export the struct field too.
-
-// LocalAddr returns the local network address.
-func (c *Conn) LocalAddr() net.Addr {
-	return c.conn.LocalAddr()
-}
-
-// RemoteAddr returns the remote network address.
-func (c *Conn) RemoteAddr() net.Addr {
-	return c.conn.RemoteAddr()
-}
-
-// SetDeadline sets the read and write deadlines associated with the connection.
-// A zero value for t means Read and Write will not time out.
-// After a Write has timed out, the TLS state is corrupt and all future writes will return the same error.
-func (c *Conn) SetDeadline(t time.Time) error {
-	return c.conn.SetDeadline(t)
-}
-
-// SetReadDeadline sets the read deadline on the underlying connection.
-// A zero value for t means Read will not time out.
-func (c *Conn) SetReadDeadline(t time.Time) error {
-	return c.conn.SetReadDeadline(t)
-}
-
-// SetWriteDeadline sets the write deadline on the underlying connection.
-// A zero value for t means Write will not time out.
-// After a Write has timed out, the TLS state is corrupt and all future writes will return the same error.
-func (c *Conn) SetWriteDeadline(t time.Time) error {
-	return c.conn.SetWriteDeadline(t)
-}
-
-// NetConn returns the underlying connection that is wrapped by c.
-// Note that writing to or reading from this connection directly will corrupt the
-// TLS session.
-func (c *Conn) NetConn() net.Conn {
-	return c.conn
-}
-
-// A halfConn represents one direction of the record layer
-// connection, either sending or receiving.
-type halfConn struct {
-	sync.Mutex
-
-	err     error  // first permanent error
-	version uint16 // protocol version
-	cipher  any    // cipher algorithm
-	mac     hash.Hash
-	seq     [8]byte // 64-bit sequence number
-
-	scratchBuf [13]byte // to avoid allocs; interface method args escape
-
-	nextCipher any       // next encryption state
-	nextMac    hash.Hash // next MAC algorithm
-
-	trafficSecret []byte // current TLS 1.3 traffic secret
-}
-
-type permanentError struct {
-	err net.Error
-}
-
-func (e *permanentError) Error() string   { return e.err.Error() }
-func (e *permanentError) Unwrap() error   { return e.err }
-func (e *permanentError) Timeout() bool   { return e.err.Timeout() }
-func (e *permanentError) Temporary() bool { return false }
-
-func (hc *halfConn) setErrorLocked(err error) error {
-	if e, ok := err.(net.Error); ok {
-		hc.err = &permanentError{err: e}
-	} else {
-		hc.err = err
-	}
-	return hc.err
-}
-
-// prepareCipherSpec sets the encryption and MAC states
-// that a subsequent changeCipherSpec will use.
-func (hc *halfConn) prepareCipherSpec(version uint16, cipher any, mac hash.Hash) {
-	hc.version = version
-	hc.nextCipher = cipher
-	hc.nextMac = mac
-}
-
-// changeCipherSpec changes the encryption and MAC states
-// to the ones previously passed to prepareCipherSpec.
-func (hc *halfConn) changeCipherSpec() error {
-	if hc.nextCipher == nil || hc.version == VersionTLS13 {
-		return alertInternalError
-	}
-	hc.cipher = hc.nextCipher
-	hc.mac = hc.nextMac
-	hc.nextCipher = nil
-	hc.nextMac = nil
-	for i := range hc.seq {
-		hc.seq[i] = 0
-	}
-	return nil
-}
-
-func (hc *halfConn) setTrafficSecret(suite *cipherSuiteTLS13, secret []byte) {
-	hc.trafficSecret = secret
-	key, iv := suite.trafficKey(secret)
-	hc.cipher = suite.aead(key, iv)
-	for i := range hc.seq {
-		hc.seq[i] = 0
-	}
-}
-
-// incSeq increments the sequence number.
-func (hc *halfConn) incSeq() {
-	for i := 7; i >= 0; i-- {
-		hc.seq[i]++
-		if hc.seq[i] != 0 {
-			return
-		}
-	}
-
-	// Not allowed to let sequence number wrap.
-	// Instead, must renegotiate before it does.
-	// Not likely enough to bother.
-	panic("TLS: sequence number wraparound")
-}
-
-// explicitNonceLen returns the number of bytes of explicit nonce or IV included
-// in each record. Explicit nonces are present only in CBC modes after TLS 1.0
-// and in certain AEAD modes in TLS 1.2.
-func (hc *halfConn) explicitNonceLen() int {
-	if hc.cipher == nil {
-		return 0
-	}
-
-	switch c := hc.cipher.(type) {
-	case cipher.Stream:
-		return 0
-	case aead:
-		return c.explicitNonceLen()
-	case cbcMode:
-		// TLS 1.1 introduced a per-record explicit IV to fix the BEAST attack.
-		if hc.version >= VersionTLS11 {
-			return c.BlockSize()
-		}
-		return 0
-	default:
-		panic("unknown cipher type")
-	}
-}
-
-// extractPadding returns, in constant time, the length of the padding to remove
-// from the end of payload. It also returns a byte which is equal to 255 if the
-// padding was valid and 0 otherwise. See RFC 2246, Section 6.2.3.2.
-func extractPadding(payload []byte) (toRemove int, good byte) {
-	if len(payload) < 1 {
-		return 0, 0
-	}
-
-	paddingLen := payload[len(payload)-1]
-	t := uint(len(payload)-1) - uint(paddingLen)
-	// if len(payload) >= (paddingLen - 1) then the MSB of t is zero
-	good = byte(int32(^t) >> 31)
-
-	// The maximum possible padding length plus the actual length field
-	toCheck := 256
-	// The length of the padded data is public, so we can use an if here
-	if toCheck > len(payload) {
-		toCheck = len(payload)
-	}
-
-	for i := 0; i < toCheck; i++ {
-		t := uint(paddingLen) - uint(i)
-		// if i <= paddingLen then the MSB of t is zero
-		mask := byte(int32(^t) >> 31)
-		b := payload[len(payload)-1-i]
-		good &^= mask&paddingLen ^ mask&b
-	}
-
-	// We AND together the bits of good and replicate the result across
-	// all the bits.
-	good &= good << 4
-	good &= good << 2
-	good &= good << 1
-	good = uint8(int8(good) >> 7)
-
-	// Zero the padding length on error. This ensures any unchecked bytes
-	// are included in the MAC. Otherwise, an attacker that could
-	// distinguish MAC failures from padding failures could mount an attack
-	// similar to POODLE in SSL 3.0: given a good ciphertext that uses a
-	// full block's worth of padding, replace the final block with another
-	// block. If the MAC check passed but the padding check failed, the
-	// last byte of that block decrypted to the block size.
-	//
-	// See also macAndPaddingGood logic below.
-	paddingLen &= good
-
-	toRemove = int(paddingLen) + 1
-	return
-}
-
-func roundUp(a, b int) int {
-	return a + (b-a%b)%b
-}
-
-// cbcMode is an interface for block ciphers using cipher block chaining.
-type cbcMode interface {
-	cipher.BlockMode
-	SetIV([]byte)
-}
-
-// decrypt authenticates and decrypts the record if protection is active at
-// this stage. The returned plaintext might overlap with the input.
-func (hc *halfConn) decrypt(record []byte) ([]byte, recordType, error) {
-	var plaintext []byte
-	typ := recordType(record[0])
-	payload := record[recordHeaderLen:]
-
-	// In TLS 1.3, change_cipher_spec messages are to be ignored without being
-	// decrypted. See RFC 8446, Appendix D.4.
-	if hc.version == VersionTLS13 && typ == recordTypeChangeCipherSpec {
-		return payload, typ, nil
-	}
-
-	paddingGood := byte(255)
-	paddingLen := 0
-
-	explicitNonceLen := hc.explicitNonceLen()
-
-	if hc.cipher != nil {
-		switch c := hc.cipher.(type) {
-		case cipher.Stream:
-			c.XORKeyStream(payload, payload)
-		case aead:
-			if len(payload) < explicitNonceLen {
-				return nil, 0, alertBadRecordMAC
-			}
-			nonce := payload[:explicitNonceLen]
-			if len(nonce) == 0 {
-				nonce = hc.seq[:]
-			}
-			payload = payload[explicitNonceLen:]
-
-			var additionalData []byte
-			if hc.version == VersionTLS13 {
-				additionalData = record[:recordHeaderLen]
-			} else {
-				additionalData = append(hc.scratchBuf[:0], hc.seq[:]...)
-				additionalData = append(additionalData, record[:3]...)
-				n := len(payload) - c.Overhead()
-				additionalData = append(additionalData, byte(n>>8), byte(n))
-			}
-
-			var err error
-			plaintext, err = c.Open(payload[:0], nonce, payload, additionalData)
-			if err != nil {
-				return nil, 0, alertBadRecordMAC
-			}
-		case cbcMode:
-			blockSize := c.BlockSize()
-			minPayload := explicitNonceLen + roundUp(hc.mac.Size()+1, blockSize)
-			if len(payload)%blockSize != 0 || len(payload) < minPayload {
-				return nil, 0, alertBadRecordMAC
-			}
-
-			if explicitNonceLen > 0 {
-				c.SetIV(payload[:explicitNonceLen])
-				payload = payload[explicitNonceLen:]
-			}
-			c.CryptBlocks(payload, payload)
-
-			// In a limited attempt to protect against CBC padding oracles like
-			// Lucky13, the data past paddingLen (which is secret) is passed to
-			// the MAC function as extra data, to be fed into the HMAC after
-			// computing the digest. This makes the MAC roughly constant time as
-			// long as the digest computation is constant time and does not
-			// affect the subsequent write, modulo cache effects.
-			paddingLen, paddingGood = extractPadding(payload)
-		default:
-			panic("unknown cipher type")
-		}
-
-		if hc.version == VersionTLS13 {
-			if typ != recordTypeApplicationData {
-				return nil, 0, alertUnexpectedMessage
-			}
-			if len(plaintext) > maxPlaintext+1 {
-				return nil, 0, alertRecordOverflow
-			}
-			// Remove padding and find the ContentType scanning from the end.
-			for i := len(plaintext) - 1; i >= 0; i-- {
-				if plaintext[i] != 0 {
-					typ = recordType(plaintext[i])
-					plaintext = plaintext[:i]
-					break
-				}
-				if i == 0 {
-					return nil, 0, alertUnexpectedMessage
-				}
-			}
-		}
-	} else {
-		plaintext = payload
-	}
-
-	if hc.mac != nil {
-		macSize := hc.mac.Size()
-		if len(payload) < macSize {
-			return nil, 0, alertBadRecordMAC
-		}
-
-		n := len(payload) - macSize - paddingLen
-		n = subtle.ConstantTimeSelect(int(uint32(n)>>31), 0, n) // if n < 0 { n = 0 }
-		record[3] = byte(n >> 8)
-		record[4] = byte(n)
-		remoteMAC := payload[n : n+macSize]
-		localMAC := tls10MAC(hc.mac, hc.scratchBuf[:0], hc.seq[:], record[:recordHeaderLen], payload[:n], payload[n+macSize:])
-
-		// This is equivalent to checking the MACs and paddingGood
-		// separately, but in constant-time to prevent distinguishing
-		// padding failures from MAC failures. Depending on what value
-		// of paddingLen was returned on bad padding, distinguishing
-		// bad MAC from bad padding can lead to an attack.
-		//
-		// See also the logic at the end of extractPadding.
-		macAndPaddingGood := subtle.ConstantTimeCompare(localMAC, remoteMAC) & int(paddingGood)
-		if macAndPaddingGood != 1 {
-			return nil, 0, alertBadRecordMAC
-		}
-
-		plaintext = payload[:n]
-	}
-
-	hc.incSeq()
-	return plaintext, typ, nil
-}
-
-// sliceForAppend extends the input slice by n bytes. head is the full extended
-// slice, while tail is the appended part. If the original slice has sufficient
-// capacity no allocation is performed.
-func sliceForAppend(in []byte, n int) (head, tail []byte) {
-	if total := len(in) + n; cap(in) >= total {
-		head = in[:total]
-	} else {
-		head = make([]byte, total)
-		copy(head, in)
-	}
-	tail = head[len(in):]
-	return
-}
-
-// encrypt encrypts payload, adding the appropriate nonce and/or MAC, and
-// appends it to record, which must already contain the record header.
-func (hc *halfConn) encrypt(record, payload []byte, rand io.Reader) ([]byte, error) {
-	if hc.cipher == nil {
-		return append(record, payload...), nil
-	}
-
-	var explicitNonce []byte
-	if explicitNonceLen := hc.explicitNonceLen(); explicitNonceLen > 0 {
-		record, explicitNonce = sliceForAppend(record, explicitNonceLen)
-		if _, isCBC := hc.cipher.(cbcMode); !isCBC && explicitNonceLen < 16 {
-			// The AES-GCM construction in TLS has an explicit nonce so that the
-			// nonce can be random. However, the nonce is only 8 bytes which is
-			// too small for a secure, random nonce. Therefore we use the
-			// sequence number as the nonce. The 3DES-CBC construction also has
-			// an 8 bytes nonce but its nonces must be unpredictable (see RFC
-			// 5246, Appendix F.3), forcing us to use randomness. That's not
-			// 3DES' biggest problem anyway because the birthday bound on block
-			// collision is reached first due to its similarly small block size
-			// (see the Sweet32 attack).
-			copy(explicitNonce, hc.seq[:])
-		} else {
-			if _, err := io.ReadFull(rand, explicitNonce); err != nil {
-				return nil, err
-			}
-		}
-	}
-
-	var dst []byte
-	switch c := hc.cipher.(type) {
-	case cipher.Stream:
-		mac := tls10MAC(hc.mac, hc.scratchBuf[:0], hc.seq[:], record[:recordHeaderLen], payload, nil)
-		record, dst = sliceForAppend(record, len(payload)+len(mac))
-		c.XORKeyStream(dst[:len(payload)], payload)
-		c.XORKeyStream(dst[len(payload):], mac)
-	case aead:
-		nonce := explicitNonce
-		if len(nonce) == 0 {
-			nonce = hc.seq[:]
-		}
-
-		if hc.version == VersionTLS13 {
-			record = append(record, payload...)
-
-			// Encrypt the actual ContentType and replace the plaintext one.
-			record = append(record, record[0])
-			record[0] = byte(recordTypeApplicationData)
-
-			n := len(payload) + 1 + c.Overhead()
-			record[3] = byte(n >> 8)
-			record[4] = byte(n)
-
-			record = c.Seal(record[:recordHeaderLen],
-				nonce, record[recordHeaderLen:], record[:recordHeaderLen])
-		} else {
-			additionalData := append(hc.scratchBuf[:0], hc.seq[:]...)
-			additionalData = append(additionalData, record[:recordHeaderLen]...)
-			record = c.Seal(record, nonce, payload, additionalData)
-		}
-	case cbcMode:
-		mac := tls10MAC(hc.mac, hc.scratchBuf[:0], hc.seq[:], record[:recordHeaderLen], payload, nil)
-		blockSize := c.BlockSize()
-		plaintextLen := len(payload) + len(mac)
-		paddingLen := blockSize - plaintextLen%blockSize
-		record, dst = sliceForAppend(record, plaintextLen+paddingLen)
-		copy(dst, payload)
-		copy(dst[len(payload):], mac)
-		for i := plaintextLen; i < len(dst); i++ {
-			dst[i] = byte(paddingLen - 1)
-		}
-		if len(explicitNonce) > 0 {
-			c.SetIV(explicitNonce)
-		}
-		c.CryptBlocks(dst, dst)
-	default:
-		panic("unknown cipher type")
-	}
-
-	// Update length to include nonce, MAC and any block padding needed.
-	n := len(record) - recordHeaderLen
-	record[3] = byte(n >> 8)
-	record[4] = byte(n)
-	hc.incSeq()
-
-	return record, nil
-}
-
-// RecordHeaderError is returned when a TLS record header is invalid.
-type RecordHeaderError struct {
-	// Msg contains a human readable string that describes the error.
-	Msg string
-	// RecordHeader contains the five bytes of TLS record header that
-	// triggered the error.
-	RecordHeader [5]byte
-	// Conn provides the underlying net.Conn in the case that a client
-	// sent an initial handshake that didn't look like TLS.
-	// It is nil if there's already been a handshake or a TLS alert has
-	// been written to the connection.
-	Conn net.Conn
-}
-
-func (e RecordHeaderError) Error() string { return "tls: " + e.Msg }
-
-func (c *Conn) newRecordHeaderError(conn net.Conn, msg string) (err RecordHeaderError) {
-	err.Msg = msg
-	err.Conn = conn
-	copy(err.RecordHeader[:], c.rawInput.Bytes())
-	return err
-}
-
-func (c *Conn) readRecord() error {
-	return c.readRecordOrCCS(false)
-}
-
-func (c *Conn) readChangeCipherSpec() error {
-	return c.readRecordOrCCS(true)
-}
-
-// readRecordOrCCS reads one or more TLS records from the connection and
-// updates the record layer state. Some invariants:
-//   - c.in must be locked
-//   - c.input must be empty
-//
-// During the handshake one and only one of the following will happen:
-//   - c.hand grows
-//   - c.in.changeCipherSpec is called
-//   - an error is returned
-//
-// After the handshake one and only one of the following will happen:
-//   - c.hand grows
-//   - c.input is set
-//   - an error is returned
-func (c *Conn) readRecordOrCCS(expectChangeCipherSpec bool) error {
-	if c.in.err != nil {
-		return c.in.err
-	}
-	handshakeComplete := c.handshakeComplete()
-
-	// This function modifies c.rawInput, which owns the c.input memory.
-	if c.input.Len() != 0 {
-		return c.in.setErrorLocked(errors.New("tls: internal error: attempted to read record with pending application data"))
-	}
-	c.input.Reset(nil)
-
-	// Read header, payload.
-	if err := c.readFromUntil(c.conn, recordHeaderLen); err != nil {
-		// RFC 8446, Section 6.1 suggests that EOF without an alertCloseNotify
-		// is an error, but popular web sites seem to do this, so we accept it
-		// if and only if at the record boundary.
-		if err == io.ErrUnexpectedEOF && c.rawInput.Len() == 0 {
-			err = io.EOF
-		}
-		if e, ok := err.(net.Error); !ok || !e.Temporary() {
-			c.in.setErrorLocked(err)
-		}
-		return err
-	}
-	hdr := c.rawInput.Bytes()[:recordHeaderLen]
-	typ := recordType(hdr[0])
-
-	// No valid TLS record has a type of 0x80, however SSLv2 handshakes
-	// start with a uint16 length where the MSB is set and the first record
-	// is always < 256 bytes long. Therefore typ == 0x80 strongly suggests
-	// an SSLv2 client.
-	if !handshakeComplete && typ == 0x80 {
-		c.sendAlert(alertProtocolVersion)
-		return c.in.setErrorLocked(c.newRecordHeaderError(nil, "unsupported SSLv2 handshake received"))
-	}
-
-	vers := uint16(hdr[1])<<8 | uint16(hdr[2])
-	n := int(hdr[3])<<8 | int(hdr[4])
-	if c.haveVers && c.vers != VersionTLS13 && vers != c.vers {
-		c.sendAlert(alertProtocolVersion)
-		msg := fmt.Sprintf("received record with version %x when expecting version %x", vers, c.vers)
-		return c.in.setErrorLocked(c.newRecordHeaderError(nil, msg))
-	}
-	if !c.haveVers {
-		// First message, be extra suspicious: this might not be a TLS
-		// client. Bail out before reading a full 'body', if possible.
-		// The current max version is 3.3 so if the version is >= 16.0,
-		// it's probably not real.
-		if (typ != recordTypeAlert && typ != recordTypeHandshake) || vers >= 0x1000 {
-			return c.in.setErrorLocked(c.newRecordHeaderError(c.conn, "first record does not look like a TLS handshake"))
-		}
-	}
-	if c.vers == VersionTLS13 && n > maxCiphertextTLS13 || n > maxCiphertext {
-		c.sendAlert(alertRecordOverflow)
-		msg := fmt.Sprintf("oversized record received with length %d", n)
-		return c.in.setErrorLocked(c.newRecordHeaderError(nil, msg))
-	}
-	if err := c.readFromUntil(c.conn, recordHeaderLen+n); err != nil {
-		if e, ok := err.(net.Error); !ok || !e.Temporary() {
-			c.in.setErrorLocked(err)
-		}
-		return err
-	}
-
-	// Process message.
-	record := c.rawInput.Next(recordHeaderLen + n)
-	data, typ, err := c.in.decrypt(record)
-	if err != nil {
-		return c.in.setErrorLocked(c.sendAlert(err.(alert)))
-	}
-	if len(data) > maxPlaintext {
-		return c.in.setErrorLocked(c.sendAlert(alertRecordOverflow))
-	}
-
-	// Application Data messages are always protected.
-	if c.in.cipher == nil && typ == recordTypeApplicationData {
-		return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
-	}
-
-	if typ != recordTypeAlert && typ != recordTypeChangeCipherSpec && len(data) > 0 {
-		// This is a state-advancing message: reset the retry count.
-		c.retryCount = 0
-	}
-
-	// Handshake messages MUST NOT be interleaved with other record types in TLS 1.3.
-	if c.vers == VersionTLS13 && typ != recordTypeHandshake && c.hand.Len() > 0 {
-		return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
-	}
-
-	switch typ {
-	default:
-		return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
-
-	case recordTypeAlert:
-		if len(data) != 2 {
-			return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
-		}
-		if alert(data[1]) == alertCloseNotify {
-			return c.in.setErrorLocked(io.EOF)
-		}
-		if c.vers == VersionTLS13 {
-			if !c.isClient && c.ech.greased && alert(data[1]) == alertECHRequired {
-				// This condition indicates that the client intended to offer
-				// ECH, but did not use a known ECH config.
-				c.ech.offered = true
-				c.ech.greased = false
-			}
-			return c.in.setErrorLocked(&net.OpError{Op: "remote error", Err: alert(data[1])})
-		}
-		switch data[0] {
-		case alertLevelWarning:
-			// Drop the record on the floor and retry.
-			return c.retryReadRecord(expectChangeCipherSpec)
-		case alertLevelError:
-			return c.in.setErrorLocked(&net.OpError{Op: "remote error", Err: alert(data[1])})
-		default:
-			return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
-		}
-
-	case recordTypeChangeCipherSpec:
-		if len(data) != 1 || data[0] != 1 {
-			return c.in.setErrorLocked(c.sendAlert(alertDecodeError))
-		}
-		// Handshake messages are not allowed to fragment across the CCS.
-		if c.hand.Len() > 0 {
-			return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
-		}
-		// In TLS 1.3, change_cipher_spec records are ignored until the
-		// Finished. See RFC 8446, Appendix D.4. Note that according to Section
-		// 5, a server can send a ChangeCipherSpec before its ServerHello, when
-		// c.vers is still unset. That's not useful though and suspicious if the
-		// server then selects a lower protocol version, so don't allow that.
-		if c.vers == VersionTLS13 {
-			return c.retryReadRecord(expectChangeCipherSpec)
-		}
-		if !expectChangeCipherSpec {
-			return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
-		}
-		if err := c.in.changeCipherSpec(); err != nil {
-			return c.in.setErrorLocked(c.sendAlert(err.(alert)))
-		}
-
-	case recordTypeApplicationData:
-		if !handshakeComplete || expectChangeCipherSpec {
-			return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
-		}
-		// Some OpenSSL servers send empty records in order to randomize the
-		// CBC IV. Ignore a limited number of empty records.
-		if len(data) == 0 {
-			return c.retryReadRecord(expectChangeCipherSpec)
-		}
-		// Note that data is owned by c.rawInput, following the Next call above,
-		// to avoid copying the plaintext. This is safe because c.rawInput is
-		// not read from or written to until c.input is drained.
-		c.input.Reset(data)
-
-	case recordTypeHandshake:
-		if len(data) == 0 || expectChangeCipherSpec {
-			return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
-		}
-		c.hand.Write(data)
-	}
-
-	return nil
-}
-
-// retryReadRecord recurses into readRecordOrCCS to drop a non-advancing record, like
-// a warning alert, empty application_data, or a change_cipher_spec in TLS 1.3.
-func (c *Conn) retryReadRecord(expectChangeCipherSpec bool) error {
-	c.retryCount++
-	if c.retryCount > maxUselessRecords {
-		c.sendAlert(alertUnexpectedMessage)
-		return c.in.setErrorLocked(errors.New("tls: too many ignored records"))
-	}
-	return c.readRecordOrCCS(expectChangeCipherSpec)
-}
-
-// atLeastReader reads from R, stopping with EOF once at least N bytes have been
-// read. It is different from an io.LimitedReader in that it doesn't cut short
-// the last Read call, and in that it considers an early EOF an error.
-type atLeastReader struct {
-	R io.Reader
-	N int64
-}
-
-func (r *atLeastReader) Read(p []byte) (int, error) {
-	if r.N <= 0 {
-		return 0, io.EOF
-	}
-	n, err := r.R.Read(p)
-	r.N -= int64(n) // won't underflow unless len(p) >= n > 9223372036854775809
-	if r.N > 0 && err == io.EOF {
-		return n, io.ErrUnexpectedEOF
-	}
-	if r.N <= 0 && err == nil {
-		return n, io.EOF
-	}
-	return n, err
-}
-
-// readFromUntil reads from r into c.rawInput until c.rawInput contains
-// at least n bytes or else returns an error.
-func (c *Conn) readFromUntil(r io.Reader, n int) error {
-	if c.rawInput.Len() >= n {
-		return nil
-	}
-	needs := n - c.rawInput.Len()
-	// There might be extra input waiting on the wire. Make a best effort
-	// attempt to fetch it so that it can be used in (*Conn).Read to
-	// "predict" closeNotify alerts.
-	c.rawInput.Grow(needs + bytes.MinRead)
-	_, err := c.rawInput.ReadFrom(&atLeastReader{r, int64(needs)})
-	return err
-}
-
-// sendAlert sends a TLS alert message.
-func (c *Conn) sendAlertLocked(err alert) error {
-	switch err {
-	case alertNoRenegotiation, alertCloseNotify:
-		c.tmp[0] = alertLevelWarning
-	default:
-		c.tmp[0] = alertLevelError
-	}
-	c.tmp[1] = byte(err)
-
-	_, writeErr := c.writeRecordLocked(recordTypeAlert, c.tmp[0:2])
-	if err == alertCloseNotify {
-		// closeNotify is a special case in that it isn't an error.
-		return writeErr
-	}
-
-	return c.out.setErrorLocked(&net.OpError{Op: "local error", Err: err})
-}
-
-// sendAlert sends a TLS alert message.
-func (c *Conn) sendAlert(err alert) error {
-	c.out.Lock()
-	defer c.out.Unlock()
-	return c.sendAlertLocked(err)
-}
-
-const (
-	// tcpMSSEstimate is a conservative estimate of the TCP maximum segment
-	// size (MSS). A constant is used, rather than querying the kernel for
-	// the actual MSS, to avoid complexity. The value here is the IPv6
-	// minimum MTU (1280 bytes) minus the overhead of an IPv6 header (40
-	// bytes) and a TCP header with timestamps (32 bytes).
-	tcpMSSEstimate = 1208
-
-	// recordSizeBoostThreshold is the number of bytes of application data
-	// sent after which the TLS record size will be increased to the
-	// maximum.
-	recordSizeBoostThreshold = 128 * 1024
-)
-
-// maxPayloadSizeForWrite returns the maximum TLS payload size to use for the
-// next application data record. There is the following trade-off:
-//
-//   - For latency-sensitive applications, such as web browsing, each TLS
-//     record should fit in one TCP segment.
-//   - For throughput-sensitive applications, such as large file transfers,
-//     larger TLS records better amortize framing and encryption overheads.
-//
-// A simple heuristic that works well in practice is to use small records for
-// the first 1MB of data, then use larger records for subsequent data, and
-// reset back to smaller records after the connection becomes idle. See "High
-// Performance Web Networking", Chapter 4, or:
-// https://www.igvita.com/2013/10/24/optimizing-tls-record-size-and-buffering-latency/
-//
-// In the interests of simplicity and determinism, this code does not attempt
-// to reset the record size once the connection is idle, however.
-func (c *Conn) maxPayloadSizeForWrite(typ recordType) int {
-	if c.config.DynamicRecordSizingDisabled || typ != recordTypeApplicationData {
-		return maxPlaintext
-	}
-
-	if c.bytesSent >= recordSizeBoostThreshold {
-		return maxPlaintext
-	}
-
-	// Subtract TLS overheads to get the maximum payload size.
-	payloadBytes := tcpMSSEstimate - recordHeaderLen - c.out.explicitNonceLen()
-	if c.out.cipher != nil {
-		switch ciph := c.out.cipher.(type) {
-		case cipher.Stream:
-			payloadBytes -= c.out.mac.Size()
-		case cipher.AEAD:
-			payloadBytes -= ciph.Overhead()
-		case cbcMode:
-			blockSize := ciph.BlockSize()
-			// The payload must fit in a multiple of blockSize, with
-			// room for at least one padding byte.
-			payloadBytes = (payloadBytes & ^(blockSize - 1)) - 1
-			// The MAC is appended before padding so affects the
-			// payload size directly.
-			payloadBytes -= c.out.mac.Size()
-		default:
-			panic("unknown cipher type")
-		}
-	}
-	if c.vers == VersionTLS13 {
-		payloadBytes-- // encrypted ContentType
-	}
-
-	// Allow packet growth in arithmetic progression up to max.
-	pkt := c.packetsSent
-	c.packetsSent++
-	if pkt > 1000 {
-		return maxPlaintext // avoid overflow in multiply below
-	}
-
-	n := payloadBytes * int(pkt+1)
-	if n > maxPlaintext {
-		n = maxPlaintext
-	}
-	return n
-}
-
-func (c *Conn) write(data []byte) (int, error) {
-	if c.buffering {
-		c.sendBuf = append(c.sendBuf, data...)
-		return len(data), nil
-	}
-
-	n, err := c.conn.Write(data)
-	c.bytesSent += int64(n)
-	return n, err
-}
-
-func (c *Conn) flush() (int, error) {
-	if len(c.sendBuf) == 0 {
-		return 0, nil
-	}
-
-	n, err := c.conn.Write(c.sendBuf)
-	c.bytesSent += int64(n)
-	c.sendBuf = nil
-	c.buffering = false
-	return n, err
-}
-
-// outBufPool pools the record-sized scratch buffers used by writeRecordLocked.
-var outBufPool = sync.Pool{
-	New: func() any {
-		return new([]byte)
-	},
-}
-
-// writeRecordLocked writes a TLS record with the given type and payload to the
-// connection and updates the record layer state.
-func (c *Conn) writeRecordLocked(typ recordType, data []byte) (int, error) {
-	outBufPtr := outBufPool.Get().(*[]byte)
-	outBuf := *outBufPtr
-	defer func() {
-		// You might be tempted to simplify this by just passing &outBuf to Put,
-		// but that would make the local copy of the outBuf slice header escape
-		// to the heap, causing an allocation. Instead, we keep around the
-		// pointer to the slice header returned by Get, which is already on the
-		// heap, and overwrite and return that.
-		*outBufPtr = outBuf
-		outBufPool.Put(outBufPtr)
-	}()
-
-	var n int
-	for len(data) > 0 {
-		m := len(data)
-		if maxPayload := c.maxPayloadSizeForWrite(typ); m > maxPayload {
-			m = maxPayload
-		}
-
-		_, outBuf = sliceForAppend(outBuf[:0], recordHeaderLen)
-		outBuf[0] = byte(typ)
-		vers := c.vers
-		if vers == 0 {
-			// Some TLS servers fail if the record version is
-			// greater than TLS 1.0 for the initial ClientHello.
-			vers = VersionTLS10
-		} else if vers == VersionTLS13 {
-			// TLS 1.3 froze the record layer version to 1.2.
-			// See RFC 8446, Section 5.1.
-			vers = VersionTLS12
-		}
-		outBuf[1] = byte(vers >> 8)
-		outBuf[2] = byte(vers)
-		outBuf[3] = byte(m >> 8)
-		outBuf[4] = byte(m)
-
-		var err error
-		outBuf, err = c.out.encrypt(outBuf, data[:m], c.config.rand())
-		if err != nil {
-			return n, err
-		}
-		if _, err := c.write(outBuf); err != nil {
-			return n, err
-		}
-		n += m
-		data = data[m:]
-	}
-
-	if typ == recordTypeChangeCipherSpec && c.vers != VersionTLS13 {
-		if err := c.out.changeCipherSpec(); err != nil {
-			return n, c.sendAlertLocked(err.(alert))
-		}
-	}
-
-	return n, nil
-}
-
-// writeRecord writes a TLS record with the given type and payload to the
-// connection and updates the record layer state.
-func (c *Conn) writeRecord(typ recordType, data []byte) (int, error) {
-	c.out.Lock()
-	defer c.out.Unlock()
-
-	return c.writeRecordLocked(typ, data)
-}
-
-// readHandshake reads the next handshake message from
-// the record layer.
-func (c *Conn) readHandshake() (any, error) {
-	for c.hand.Len() < 4 {
-		if err := c.readRecord(); err != nil {
-			return nil, err
-		}
-	}
-
-	data := c.hand.Bytes()
-	n := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
-	if n > maxHandshake {
-		c.sendAlertLocked(alertInternalError)
-		return nil, c.in.setErrorLocked(fmt.Errorf("tls: handshake message of length %d bytes exceeds maximum of %d bytes", n, maxHandshake))
-	}
-	for c.hand.Len() < 4+n {
-		if err := c.readRecord(); err != nil {
-			return nil, err
-		}
-	}
-	data = c.hand.Next(4 + n)
-	var m handshakeMessage
-	switch data[0] {
-	case typeHelloRequest:
-		m = new(helloRequestMsg)
-	case typeClientHello:
-		m = new(clientHelloMsg)
-	case typeServerHello:
-		m = new(serverHelloMsg)
-	case typeNewSessionTicket:
-		if c.vers == VersionTLS13 {
-			m = new(newSessionTicketMsgTLS13)
-		} else {
-			m = new(newSessionTicketMsg)
-		}
-	case typeCertificate:
-		if c.vers == VersionTLS13 {
-			m = new(certificateMsgTLS13)
-		} else {
-			m = new(certificateMsg)
-		}
-	case typeCertificateRequest:
-		if c.vers == VersionTLS13 {
-			m = new(certificateRequestMsgTLS13)
-		} else {
-			m = &certificateRequestMsg{
-				hasSignatureAlgorithm: c.vers >= VersionTLS12,
-			}
-		}
-	case typeCertificateStatus:
-		m = new(certificateStatusMsg)
-	case typeServerKeyExchange:
-		m = new(serverKeyExchangeMsg)
-	case typeServerHelloDone:
-		m = new(serverHelloDoneMsg)
-	case typeClientKeyExchange:
-		m = new(clientKeyExchangeMsg)
-	case typeCertificateVerify:
-		m = &certificateVerifyMsg{
-			hasSignatureAlgorithm: c.vers >= VersionTLS12,
-		}
-	case typeFinished:
-		m = new(finishedMsg)
-	case typeEncryptedExtensions:
-		m = new(encryptedExtensionsMsg)
-	case typeEndOfEarlyData:
-		m = new(endOfEarlyDataMsg)
-	case typeKeyUpdate:
-		m = new(keyUpdateMsg)
-	default:
-		return nil, c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
-	}
-
-	// The handshake message unmarshalers
-	// expect to be able to keep references to data,
-	// so pass in a fresh copy that won't be overwritten.
-	data = append([]byte(nil), data...)
-
-	if !m.unmarshal(data) {
-		return nil, c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
-	}
-	return m, nil
-}
-
-var errShutdown = errors.New("tls: protocol is shutdown")
-
-// Write writes data to the connection.
-//
-// As Write calls Handshake, in order to prevent indefinite blocking a deadline
-// must be set for both Read and Write before Write is called when the handshake
-// has not yet completed. See SetDeadline, SetReadDeadline, and
-// SetWriteDeadline.
-func (c *Conn) Write(b []byte) (int, error) {
-	// interlock with Close below
-	for {
-		x := atomic.LoadInt32(&c.activeCall)
-		if x&1 != 0 {
-			return 0, net.ErrClosed
-		}
-		if atomic.CompareAndSwapInt32(&c.activeCall, x, x+2) {
-			break
-		}
-	}
-	defer atomic.AddInt32(&c.activeCall, -2)
-
-	if err := c.Handshake(); err != nil {
-		return 0, err
-	}
-
-	c.out.Lock()
-	defer c.out.Unlock()
-
-	if err := c.out.err; err != nil {
-		return 0, err
-	}
-
-	if !c.handshakeComplete() {
-		return 0, alertInternalError
-	}
-
-	if c.closeNotifySent {
-		return 0, errShutdown
-	}
-
-	// TLS 1.0 is susceptible to a chosen-plaintext
-	// attack when using block mode ciphers due to predictable IVs.
-	// This can be prevented by splitting each Application Data
-	// record into two records, effectively randomizing the IV.
-	//
-	// https://www.openssl.org/~bodo/tls-cbc.txt
-	// https://bugzilla.mozilla.org/show_bug.cgi?id=665814
-	// https://www.imperialviolet.org/2012/01/15/beastfollowup.html
-
-	var m int
-	if len(b) > 1 && c.vers == VersionTLS10 {
-		if _, ok := c.out.cipher.(cipher.BlockMode); ok {
-			n, err := c.writeRecordLocked(recordTypeApplicationData, b[:1])
-			if err != nil {
-				return n, c.out.setErrorLocked(err)
-			}
-			m, b = 1, b[1:]
-		}
-	}
-
-	n, err := c.writeRecordLocked(recordTypeApplicationData, b)
-	return n + m, c.out.setErrorLocked(err)
-}
-
-// handleRenegotiation processes a HelloRequest handshake message.
-func (c *Conn) handleRenegotiation() error {
-	if c.vers == VersionTLS13 {
-		return errors.New("tls: internal error: unexpected renegotiation")
-	}
-
-	msg, err := c.readHandshake()
-	if err != nil {
-		return err
-	}
-
-	helloReq, ok := msg.(*helloRequestMsg)
-	if !ok {
-		c.sendAlert(alertUnexpectedMessage)
-		return unexpectedMessageError(helloReq, msg)
-	}
-
-	if !c.isClient {
-		return c.sendAlert(alertNoRenegotiation)
-	}
-
-	switch c.config.Renegotiation {
-	case RenegotiateNever:
-		return c.sendAlert(alertNoRenegotiation)
-	case RenegotiateOnceAsClient:
-		if c.handshakes > 1 {
-			return c.sendAlert(alertNoRenegotiation)
-		}
-	case RenegotiateFreelyAsClient:
-		// Ok.
-	default:
-		c.sendAlert(alertInternalError)
-		return errors.New("tls: unknown Renegotiation value")
-	}
-
-	c.handshakeMutex.Lock()
-	defer c.handshakeMutex.Unlock()
-
-	atomic.StoreUint32(&c.handshakeStatus, 0)
-	if c.handshakeErr = c.clientHandshake(context.Background()); c.handshakeErr == nil {
-		c.handshakes++
-	}
-	return c.handshakeErr
-}
-
-// handlePostHandshakeMessage processes a handshake message arrived after the
-// handshake is complete. Up to TLS 1.2, it indicates the start of a renegotiation.
-func (c *Conn) handlePostHandshakeMessage() error {
-	if c.vers != VersionTLS13 {
-		return c.handleRenegotiation()
-	}
-
-	msg, err := c.readHandshake()
-	if err != nil {
-		return err
-	}
-
-	c.retryCount++
-	if c.retryCount > maxUselessRecords {
-		c.sendAlert(alertUnexpectedMessage)
-		return c.in.setErrorLocked(errors.New("tls: too many non-advancing records"))
-	}
-
-	switch msg := msg.(type) {
-	case *newSessionTicketMsgTLS13:
-		return c.handleNewSessionTicket(msg)
-	case *keyUpdateMsg:
-		return c.handleKeyUpdate(msg)
-	default:
-		c.sendAlert(alertUnexpectedMessage)
-		return fmt.Errorf("tls: received unexpected handshake message of type %T", msg)
-	}
-}
-
-func (c *Conn) handleKeyUpdate(keyUpdate *keyUpdateMsg) error {
-	cipherSuite := cipherSuiteTLS13ByID(c.cipherSuite)
-	if cipherSuite == nil {
-		return c.in.setErrorLocked(c.sendAlert(alertInternalError))
-	}
-
-	newSecret := cipherSuite.nextTrafficSecret(c.in.trafficSecret)
-	c.in.setTrafficSecret(cipherSuite, newSecret)
-
-	if keyUpdate.updateRequested {
-		c.out.Lock()
-		defer c.out.Unlock()
-
-		msg := &keyUpdateMsg{}
-		_, err := c.writeRecordLocked(recordTypeHandshake, msg.marshal())
-		if err != nil {
-			// Surface the error at the next write.
-			c.out.setErrorLocked(err)
-			return nil
-		}
-
-		newSecret := cipherSuite.nextTrafficSecret(c.out.trafficSecret)
-		c.out.setTrafficSecret(cipherSuite, newSecret)
-	}
-
-	return nil
-}
-
-// Read reads data from the connection.
-//
-// As Read calls Handshake, in order to prevent indefinite blocking a deadline
-// must be set for both Read and Write before Read is called when the handshake
-// has not yet completed. See SetDeadline, SetReadDeadline, and
-// SetWriteDeadline.
-func (c *Conn) Read(b []byte) (int, error) {
-	if err := c.Handshake(); err != nil {
-		return 0, err
-	}
-	if len(b) == 0 {
-		// Put this after Handshake, in case people were calling
-		// Read(nil) for the side effect of the Handshake.
-		return 0, nil
-	}
-
-	c.in.Lock()
-	defer c.in.Unlock()
-
-	for c.input.Len() == 0 {
-		if err := c.readRecord(); err != nil {
-			return 0, err
-		}
-		for c.hand.Len() > 0 {
-			if err := c.handlePostHandshakeMessage(); err != nil {
-				return 0, err
-			}
-		}
-	}
-
-	n, _ := c.input.Read(b)
-
-	// If a close-notify alert is waiting, read it so that we can return (n,
-	// EOF) instead of (n, nil), to signal to the HTTP response reading
-	// goroutine that the connection is now closed. This eliminates a race
-	// where the HTTP response reading goroutine would otherwise not observe
-	// the EOF until its next read, by which time a client goroutine might
-	// have already tried to reuse the HTTP connection for a new request.
-	// See https://golang.org/cl/76400046 and https://golang.org/issue/3514
-	if n != 0 && c.input.Len() == 0 && c.rawInput.Len() > 0 &&
-		recordType(c.rawInput.Bytes()[0]) == recordTypeAlert {
-		if err := c.readRecord(); err != nil {
-			return n, err // will be io.EOF on closeNotify
-		}
-	}
-
-	return n, nil
-}
-
-// Close closes the connection.
-func (c *Conn) Close() error {
-	// Interlock with Conn.Write above.
-	var x int32
-	for {
-		x = atomic.LoadInt32(&c.activeCall)
-		if x&1 != 0 {
-			return net.ErrClosed
-		}
-		if atomic.CompareAndSwapInt32(&c.activeCall, x, x|1) {
-			break
-		}
-	}
-	if x != 0 {
-		// io.Writer and io.Closer should not be used concurrently.
-		// If Close is called while a Write is currently in-flight,
-		// interpret that as a sign that this Close is really just
-		// being used to break the Write and/or clean up resources and
-		// avoid sending the alertCloseNotify, which may block
-		// waiting on handshakeMutex or the c.out mutex.
-		return c.conn.Close()
-	}
-
-	var alertErr error
-	if c.handshakeComplete() {
-		if err := c.closeNotify(); err != nil {
-			alertErr = fmt.Errorf("tls: failed to send closeNotify alert (but connection was closed anyway): %w", err)
-		}
-	}
-
-	if err := c.conn.Close(); err != nil {
-		return err
-	}
-
-	// Resolve ECH status.
-	if !c.isClient && c.config.MaxVersion < VersionTLS13 {
-		c.handleCFEvent(CFEventECHServerStatus(echStatusBypassed))
-	} else if !c.ech.offered {
-		if !c.ech.greased {
-			c.handleCFEvent(CFEventECHClientStatus(echStatusBypassed))
-		} else {
-			c.handleCFEvent(CFEventECHClientStatus(echStatusOuter))
-		}
-	} else {
-		c.handleCFEvent(CFEventECHClientStatus(echStatusInner))
-		if !c.ech.accepted {
-			if len(c.ech.retryConfigs) > 0 {
-				c.handleCFEvent(CFEventECHServerStatus(echStatusOuter))
-			} else {
-				c.handleCFEvent(CFEventECHServerStatus(echStatusBypassed))
-			}
-		} else {
-			c.handleCFEvent(CFEventECHServerStatus(echStatusInner))
-		}
-	}
-
-	return alertErr
-}
-
-var errEarlyCloseWrite = errors.New("tls: CloseWrite called before handshake complete")
-
-// CloseWrite shuts down the writing side of the connection. It should only be
-// called once the handshake has completed and does not call CloseWrite on the
-// underlying connection. Most callers should just use Close.
-func (c *Conn) CloseWrite() error {
-	if !c.handshakeComplete() {
-		return errEarlyCloseWrite
-	}
-
-	return c.closeNotify()
-}
-
-func (c *Conn) closeNotify() error {
-	c.out.Lock()
-	defer c.out.Unlock()
-
-	if !c.closeNotifySent {
-		// Set a Write Deadline to prevent possibly blocking forever.
-		c.SetWriteDeadline(time.Now().Add(time.Second * 5))
-		c.closeNotifyErr = c.sendAlertLocked(alertCloseNotify)
-		c.closeNotifySent = true
-		// Any subsequent writes will fail.
-		c.SetWriteDeadline(time.Now())
-	}
-	return c.closeNotifyErr
-}
-
-// Handshake runs the client or server handshake
-// protocol if it has not yet been run.
-//
-// Most uses of this package need not call Handshake explicitly: the
-// first Read or Write will call it automatically.
-//
-// For control over canceling or setting a timeout on a handshake, use
-// HandshakeContext or the Dialer's DialContext method instead.
-func (c *Conn) Handshake() error {
-	return c.HandshakeContext(context.Background())
-}
-
-// HandshakeContext runs the client or server handshake
-// protocol if it has not yet been run.
-//
-// The provided Context must be non-nil. If the context is canceled before
-// the handshake is complete, the handshake is interrupted and an error is returned.
-// Once the handshake has completed, cancellation of the context will not affect the
-// connection.
-//
-// Most uses of this package need not call HandshakeContext explicitly: the
-// first Read or Write will call it automatically.
-func (c *Conn) HandshakeContext(ctx context.Context) error {
-	// Delegate to unexported method for named return
-	// without confusing documented signature.
-	return c.handshakeContext(ctx)
-}
-
-func (c *Conn) handshakeContext(ctx context.Context) (ret error) {
-	// Fast sync/atomic-based exit if there is no handshake in flight and the
-	// last one succeeded without an error. Avoids the expensive context setup
-	// and mutex for most Read and Write calls.
-	if c.handshakeComplete() {
-		return nil
-	}
-
-	handshakeCtx, cancel := context.WithCancel(ctx)
-	// Note: defer this before starting the "interrupter" goroutine
-	// so that we can tell the difference between the input being canceled and
-	// this cancellation. In the former case, we need to close the connection.
-	defer cancel()
-
-	// Start the "interrupter" goroutine, if this context might be canceled.
-	// (The background context cannot).
-	//
-	// The interrupter goroutine waits for the input context to be done and
-	// closes the connection if this happens before the function returns.
-	if ctx.Done() != nil {
-		done := make(chan struct{})
-		interruptRes := make(chan error, 1)
-		defer func() {
-			close(done)
-			if ctxErr := <-interruptRes; ctxErr != nil {
-				// Return context error to user.
-				ret = ctxErr
-			}
-		}()
-		go func() {
-			select {
-			case <-handshakeCtx.Done():
-				// Close the connection, discarding the error
-				_ = c.conn.Close()
-				interruptRes <- handshakeCtx.Err()
-			case <-done:
-				interruptRes <- nil
-			}
-		}()
-	}
-
-	c.handshakeMutex.Lock()
-	defer c.handshakeMutex.Unlock()
-
-	if err := c.handshakeErr; err != nil {
-		return err
-	}
-	if c.handshakeComplete() {
-		return nil
-	}
-
-	c.in.Lock()
-	defer c.in.Unlock()
-
-	c.handshakeErr = c.handshakeFn(handshakeCtx)
-	if c.handshakeErr == nil {
-		c.handshakes++
-	} else {
-		// If an error occurred during the handshake try to flush the
-		// alert that might be left in the buffer.
-		c.flush()
-	}
-
-	if c.handshakeErr == nil && !c.handshakeComplete() {
-		c.handshakeErr = errors.New("tls: internal error: handshake should have had a result")
-	}
-	if c.handshakeErr != nil && c.handshakeComplete() {
-		panic("tls: internal error: handshake returned an error but is marked successful")
-	}
-
-	return c.handshakeErr
-}
-
-// ConnectionState returns basic TLS details about the connection.
-func (c *Conn) ConnectionState() ConnectionState {
-	c.handshakeMutex.Lock()
-	defer c.handshakeMutex.Unlock()
-	return c.connectionStateLocked()
-}
-
-func (c *Conn) connectionStateLocked() ConnectionState {
-	var state ConnectionState
-	state.HandshakeComplete = c.handshakeComplete()
-	state.Version = c.vers
-	state.NegotiatedProtocol = c.clientProtocol
-	state.DidResume = c.didResume
-	state.NegotiatedProtocolIsMutual = true
-	state.ServerName = c.serverName
-	state.CipherSuite = c.cipherSuite
-	state.PeerCertificates = c.peerCertificates
-	state.VerifiedChains = c.verifiedChains
-	if c.verifiedDC != nil {
-		state.VerifiedDC = true
-	}
-	state.SignedCertificateTimestamps = c.scts
-	state.OCSPResponse = c.ocspResponse
-	state.ECHAccepted = c.ech.accepted
-	state.ECHOffered = c.ech.offered || c.ech.greased
-	state.CFControl = c.config.CFControl
-	if !c.didResume && c.vers != VersionTLS13 {
-		if c.clientFinishedIsFirst {
-			state.TLSUnique = c.clientFinished[:]
-		} else {
-			state.TLSUnique = c.serverFinished[:]
-		}
-	}
-	if c.config.Renegotiation != RenegotiateNever {
-		state.ekm = noExportedKeyingMaterial
-	} else {
-		state.ekm = c.ekm
-	}
-	return state
-}
-
-// OCSPResponse returns the stapled OCSP response from the TLS server, if
-// any. (Only valid for client connections.)
-func (c *Conn) OCSPResponse() []byte {
-	c.handshakeMutex.Lock()
-	defer c.handshakeMutex.Unlock()
-
-	return c.ocspResponse
-}
-
-// VerifyHostname checks that the peer certificate chain is valid for
-// connecting to host. If so, it returns nil; if not, it returns an error
-// describing the problem.
-func (c *Conn) VerifyHostname(host string) error {
-	c.handshakeMutex.Lock()
-	defer c.handshakeMutex.Unlock()
-	if !c.isClient {
-		return errors.New("tls: VerifyHostname called on TLS server connection")
-	}
-	if !c.handshakeComplete() {
-		return errors.New("tls: handshake has not yet been performed")
-	}
-	if len(c.verifiedChains) == 0 {
-		return errors.New("tls: handshake did not verify certificate chain")
-	}
-	return c.peerCertificates[0].VerifyHostname(host)
-}
-
-func (c *Conn) handshakeComplete() bool {
-	return atomic.LoadUint32(&c.handshakeStatus) == 1
-}
-
-func (c *Conn) handleCFEvent(event CFEvent) {
-	if c.config.CFEventHandler != nil {
-		c.config.CFEventHandler(event)
-	}
-}

+ 0 - 550
transport/cloudflaretls/delegated_credentials.go

@@ -1,550 +0,0 @@
-// Copyright 2020-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
-
-// Delegated Credentials for TLS
-// (https://tools.ietf.org/html/draft-ietf-tls-subcerts) is an IETF Internet
-// draft and proposed TLS extension. If the client or server supports this
-// extension, then the server or client may use a "delegated credential" as the
-// signing key in the handshake. A delegated credential is a short lived
-// public/secret key pair delegated to the peer by an entity trusted by the
-// corresponding peer. This allows a reverse proxy to terminate a TLS connection
-// on behalf of the entity. Credentials can't be revoked; in order to
-// mitigate risk in case the reverse proxy is compromised, the credential is only
-// valid for a short time (days, hours, or even minutes).
-
-import (
-	"bytes"
-	"crypto"
-	"crypto/ecdsa"
-	"crypto/ed25519"
-	"crypto/elliptic"
-	"crypto/rand"
-	"crypto/rsa"
-	"crypto/x509"
-	"encoding/binary"
-	"errors"
-	"fmt"
-	"io"
-	"time"
-
-	"golang.org/x/crypto/cryptobyte"
-)
-
-const (
-	// In the absence of an application profile standard specifying otherwise,
-	// the maximum validity period is set to 7 days.
-	dcMaxTTLSeconds   = 60 * 60 * 24 * 7
-	dcMaxTTL          = time.Duration(dcMaxTTLSeconds * time.Second)
-	dcMaxPubLen       = (1 << 24) - 1 // Bytes
-	dcMaxSignatureLen = (1 << 16) - 1 // Bytes
-)
-
-const (
-	undefinedSignatureScheme SignatureScheme = 0x0000
-)
-
-var extensionDelegatedCredential = []int{1, 3, 6, 1, 4, 1, 44363, 44}
-
-// isValidForDelegation returns true if a certificate can be used for Delegated
-// Credentials.
-func isValidForDelegation(cert *x509.Certificate) bool {
-	// Check that the digitalSignature key usage is set.
-	// The certificate must contains the digitalSignature KeyUsage.
-	if (cert.KeyUsage & x509.KeyUsageDigitalSignature) == 0 {
-		return false
-	}
-
-	// Check that the certificate has the DelegationUsage extension and that
-	// it's marked as non-critical (See Section 4.2 of RFC5280).
-	for _, extension := range cert.Extensions {
-		if extension.Id.Equal(extensionDelegatedCredential) {
-			if extension.Critical {
-				return false
-			}
-			return true
-		}
-	}
-	return false
-}
-
-// isExpired returns true if the credential has expired. The end of the validity
-// interval is defined as the delegator certificate's notBefore field ('start')
-// plus dc.cred.validTime seconds. This function simply checks that the current time
-// ('now') is before the end of the validity interval.
-func (dc *DelegatedCredential) isExpired(start, now time.Time) bool {
-	end := start.Add(dc.cred.validTime)
-	return !now.Before(end)
-}
-
-// invalidTTL returns true if the credential's validity period is longer than the
-// maximum permitted. This is defined by the certificate's notBefore field
-// ('start') plus the dc.validTime, minus the current time ('now').
-func (dc *DelegatedCredential) invalidTTL(start, now time.Time) bool {
-	return dc.cred.validTime > (now.Sub(start) + dcMaxTTL).Round(time.Second)
-}
-
-// credential stores the public components of a Delegated Credential.
-type credential struct {
-	// The amount of time for which the credential is valid. Specifically, the
-	// the credential expires 'validTime' seconds after the 'notBefore' of the
-	// delegation certificate. The delegator shall not issue Delegated
-	// Credentials that are valid for more than 7 days from the current time.
-	//
-	// When this data structure is serialized, this value is converted to a
-	// uint32 representing the duration in seconds.
-	validTime time.Duration
-	// The signature scheme associated with the credential public key.
-	// This is expected to be the same as the CertificateVerify.algorithm
-	// sent by the client or server.
-	expCertVerfAlgo SignatureScheme
-	// The credential's public key.
-	publicKey crypto.PublicKey
-}
-
-// DelegatedCredential stores a Delegated Credential with the credential and its
-// signature.
-type DelegatedCredential struct {
-	// The serialized form of the Delegated Credential.
-	raw []byte
-
-	// Cred stores the public components of a Delegated Credential.
-	cred *credential
-
-	// The signature scheme used to sign the Delegated Credential.
-	algorithm SignatureScheme
-
-	// The Credential's delegation: a signature that binds the credential to
-	// the end-entity certificate's public key.
-	signature []byte
-}
-
-// marshalPublicKeyInfo returns a DER encoded PublicKeyInfo
-// from a Delegated Credential (as defined in the X.509 standard).
-// The following key types are currently supported: *ecdsa.PublicKey
-// and ed25519.PublicKey. Unsupported key types result in an error.
-// rsa.PublicKey is not supported as defined by the draft.
-func (cred *credential) marshalPublicKeyInfo() ([]byte, error) {
-	switch cred.expCertVerfAlgo {
-	case ECDSAWithP256AndSHA256,
-		ECDSAWithP384AndSHA384,
-		ECDSAWithP521AndSHA512,
-		Ed25519:
-		rawPub, err := x509.MarshalPKIXPublicKey(cred.publicKey)
-		if err != nil {
-			return nil, err
-		}
-
-		return rawPub, nil
-
-	default:
-		return nil, fmt.Errorf("tls: unsupported signature scheme: 0x%04x", cred.expCertVerfAlgo)
-	}
-}
-
-// marshal encodes the credential struct of the Delegated Credential.
-func (cred *credential) marshal() ([]byte, error) {
-	var b cryptobyte.Builder
-
-	b.AddUint32(uint32(cred.validTime / time.Second))
-	b.AddUint16(uint16(cred.expCertVerfAlgo))
-
-	// Encode the public key
-	rawPub, err := cred.marshalPublicKeyInfo()
-	if err != nil {
-		return nil, err
-	}
-	// Assert that the public key encoding is no longer than 2^24-1 bytes.
-	if len(rawPub) > dcMaxPubLen {
-		return nil, errors.New("tls: public key length exceeds 2^24-1 limit")
-	}
-
-	b.AddUint24(uint32(len(rawPub)))
-	b.AddBytes(rawPub)
-
-	raw := b.BytesOrPanic()
-	return raw, nil
-}
-
-// unmarshalCredential decodes serialized bytes and returns a credential, if possible.
-func unmarshalCredential(raw []byte) (*credential, error) {
-	if len(raw) < 10 {
-		return nil, errors.New("tls: Delegated Credential is not valid: invalid length")
-	}
-
-	s := cryptobyte.String(raw)
-	var t uint32
-	if !s.ReadUint32(&t) {
-		return nil, errors.New("tls: Delegated Credential is not valid")
-	}
-	validTime := time.Duration(t) * time.Second
-
-	var pubAlgo uint16
-	if !s.ReadUint16(&pubAlgo) {
-		return nil, errors.New("tls: Delegated Credential is not valid")
-	}
-	algo := SignatureScheme(pubAlgo)
-
-	var pubLen uint32
-	s.ReadUint24(&pubLen)
-
-	pubKey, err := x509.ParsePKIXPublicKey(s)
-	if err != nil {
-		return nil, err
-	}
-
-	return &credential{validTime, algo, pubKey}, nil
-}
-
-// getCredentialLen returns the number of bytes comprising the serialized
-// credential struct inside the Delegated Credential.
-func getCredentialLen(raw []byte) (int, error) {
-	if len(raw) < 10 {
-		return 0, errors.New("tls: Delegated Credential is not valid")
-	}
-
-	var read []byte
-	s := cryptobyte.String(raw)
-	s.ReadBytes(&read, 6)
-
-	var pubLen uint32
-	s.ReadUint24(&pubLen)
-	if !(pubLen > 0) {
-		return 0, errors.New("tls: Delegated Credential is not valid")
-	}
-
-	raw = raw[6:]
-	if len(raw) < int(pubLen) {
-		return 0, errors.New("tls: Delegated Credential is not valid")
-	}
-
-	return 9 + int(pubLen), nil
-}
-
-// getHash maps the SignatureScheme to its corresponding hash function.
-func getHash(scheme SignatureScheme) crypto.Hash {
-	switch scheme {
-	case ECDSAWithP256AndSHA256:
-		return crypto.SHA256
-	case ECDSAWithP384AndSHA384:
-		return crypto.SHA384
-	case ECDSAWithP521AndSHA512:
-		return crypto.SHA512
-	case Ed25519:
-		return directSigning
-	case PKCS1WithSHA256, PSSWithSHA256:
-		return crypto.SHA256
-	case PSSWithSHA384:
-		return crypto.SHA384
-	case PSSWithSHA512:
-		return crypto.SHA512
-	default:
-		return 0 // Unknown hash function
-	}
-}
-
-// getECDSACurve maps the SignatureScheme to its corresponding ecdsa elliptic.Curve.
-func getECDSACurve(scheme SignatureScheme) elliptic.Curve {
-	switch scheme {
-	case ECDSAWithP256AndSHA256:
-		return elliptic.P256()
-	case ECDSAWithP384AndSHA384:
-		return elliptic.P384()
-	case ECDSAWithP521AndSHA512:
-		return elliptic.P521()
-	default:
-		return nil
-	}
-}
-
-// prepareDelegationSignatureInput returns the message that the delegator is going to sign.
-func prepareDelegationSignatureInput(hash crypto.Hash, cred *credential, dCert []byte, algo SignatureScheme, isClient bool) ([]byte, error) {
-	header := make([]byte, 64)
-	for i := range header {
-		header[i] = 0x20
-	}
-
-	var context string
-	if !isClient {
-		context = "TLS, server delegated credentials\x00"
-	} else {
-		context = "TLS, client delegated credentials\x00"
-	}
-
-	rawCred, err := cred.marshal()
-	if err != nil {
-		return nil, err
-	}
-
-	var rawAlgo [2]byte
-	binary.BigEndian.PutUint16(rawAlgo[:], uint16(algo))
-
-	if hash == directSigning {
-		b := &bytes.Buffer{}
-		b.Write(header)
-		io.WriteString(b, context)
-		b.Write(dCert)
-		b.Write(rawCred)
-		b.Write(rawAlgo[:])
-		return b.Bytes(), nil
-	}
-
-	h := hash.New()
-	h.Write(header)
-	io.WriteString(h, context)
-	h.Write(dCert)
-	h.Write(rawCred)
-	h.Write(rawAlgo[:])
-	return h.Sum(nil), nil
-}
-
-// Extract the algorithm used to sign the Delegated Credential from the
-// end-entity (leaf) certificate.
-func getSignatureAlgorithm(cert *Certificate) (SignatureScheme, error) {
-	switch sk := cert.PrivateKey.(type) {
-	case *ecdsa.PrivateKey:
-		pk := sk.Public().(*ecdsa.PublicKey)
-		curveName := pk.Curve.Params().Name
-		certAlg := cert.Leaf.PublicKeyAlgorithm
-		if certAlg == x509.ECDSA && curveName == "P-256" {
-			return ECDSAWithP256AndSHA256, nil
-		} else if certAlg == x509.ECDSA && curveName == "P-384" {
-			return ECDSAWithP384AndSHA384, nil
-		} else if certAlg == x509.ECDSA && curveName == "P-521" {
-			return ECDSAWithP521AndSHA512, nil
-		} else {
-			return undefinedSignatureScheme, fmt.Errorf("using curve %s for %s is not supported", curveName, cert.Leaf.SignatureAlgorithm)
-		}
-	case ed25519.PrivateKey:
-		return Ed25519, nil
-	case *rsa.PrivateKey:
-		// If the certificate has the RSAEncryption OID there are a number of valid signature schemes that may sign the DC.
-		// In the absence of better information, we make a reasonable choice.
-		return PSSWithSHA256, nil
-	default:
-		return undefinedSignatureScheme, fmt.Errorf("tls: unsupported algorithm for signing Delegated Credential")
-	}
-}
-
-// NewDelegatedCredential creates a new Delegated Credential using 'cert' for
-// delegation, depending if the caller is the client or the server (defined by
-// 'isClient'). It generates a public/private key pair for the provided signature
-// algorithm ('pubAlgo') and it defines a validity interval (defined
-// by 'cert.Leaf.notBefore' and 'validTime'). It signs the Delegated Credential
-// using 'cert.PrivateKey'.
-func NewDelegatedCredential(cert *Certificate, pubAlgo SignatureScheme, validTime time.Duration, isClient bool) (*DelegatedCredential, crypto.PrivateKey, error) {
-	// The granularity of DC validity is seconds.
-	validTime = validTime.Round(time.Second)
-
-	// Parse the leaf certificate if needed.
-	var err error
-	if cert.Leaf == nil {
-		if len(cert.Certificate[0]) == 0 {
-			return nil, nil, errors.New("tls: missing leaf certificate for Delegated Credential")
-		}
-		cert.Leaf, err = x509.ParseCertificate(cert.Certificate[0])
-		if err != nil {
-			return nil, nil, err
-		}
-	}
-
-	// Check that the leaf certificate can be used for delegation.
-	if !isValidForDelegation(cert.Leaf) {
-		return nil, nil, errors.New("tls: certificate not authorized for delegation")
-	}
-
-	sigAlgo, err := getSignatureAlgorithm(cert)
-	if err != nil {
-		return nil, nil, err
-	}
-
-	// Generate the Delegated Credential key pair based on the provided scheme
-	var privK crypto.PrivateKey
-	var pubK crypto.PublicKey
-	switch pubAlgo {
-	case ECDSAWithP256AndSHA256,
-		ECDSAWithP384AndSHA384,
-		ECDSAWithP521AndSHA512:
-		privK, err = ecdsa.GenerateKey(getECDSACurve(pubAlgo), rand.Reader)
-		if err != nil {
-			return nil, nil, err
-		}
-		pubK = privK.(*ecdsa.PrivateKey).Public()
-	case Ed25519:
-		pubK, privK, err = ed25519.GenerateKey(rand.Reader)
-		if err != nil {
-			return nil, nil, err
-		}
-	default:
-		return nil, nil, fmt.Errorf("tls: unsupported algorithm for Delegated Credential: %s", pubAlgo)
-	}
-
-	// Prepare the credential for signing
-	hash := getHash(sigAlgo)
-	credential := &credential{validTime, pubAlgo, pubK}
-	values, err := prepareDelegationSignatureInput(hash, credential, cert.Leaf.Raw, sigAlgo, isClient)
-	if err != nil {
-		return nil, nil, err
-	}
-
-	var sig []byte
-	switch sk := cert.PrivateKey.(type) {
-	case *ecdsa.PrivateKey:
-		opts := crypto.SignerOpts(hash)
-		sig, err = sk.Sign(rand.Reader, values, opts)
-		if err != nil {
-			return nil, nil, err
-		}
-	case ed25519.PrivateKey:
-		opts := crypto.SignerOpts(hash)
-		sig, err = sk.Sign(rand.Reader, values, opts)
-		if err != nil {
-			return nil, nil, err
-		}
-	case *rsa.PrivateKey:
-		opts := &rsa.PSSOptions{
-			SaltLength: rsa.PSSSaltLengthEqualsHash,
-			Hash:       hash,
-		}
-		sig, err = rsa.SignPSS(rand.Reader, sk, hash, values, opts)
-		if err != nil {
-			return nil, nil, err
-		}
-	default:
-		return nil, nil, fmt.Errorf("tls: unsupported key type for Delegated Credential")
-	}
-
-	if len(sig) > dcMaxSignatureLen {
-		return nil, nil, errors.New("tls: unable to create a Delegated Credential")
-	}
-
-	return &DelegatedCredential{
-		cred:      credential,
-		algorithm: sigAlgo,
-		signature: sig,
-	}, privK, nil
-}
-
-// Validate validates the Delegated Credential by checking that the signature is
-// valid, that it hasn't expired, and that the TTL is valid. It also checks that
-// certificate can be used for delegation.
-func (dc *DelegatedCredential) Validate(cert *x509.Certificate, isClient bool, now time.Time, certVerifyMsg *certificateVerifyMsg) bool {
-	if dc.isExpired(cert.NotBefore, now) {
-		return false
-	}
-
-	if dc.invalidTTL(cert.NotBefore, now) {
-		return false
-	}
-
-	if dc.cred.expCertVerfAlgo != certVerifyMsg.signatureAlgorithm {
-		return false
-	}
-
-	if !isValidForDelegation(cert) {
-		return false
-	}
-
-	hash := getHash(dc.algorithm)
-	in, err := prepareDelegationSignatureInput(hash, dc.cred, cert.Raw, dc.algorithm, isClient)
-	if err != nil {
-		return false
-	}
-
-	switch dc.algorithm {
-	case ECDSAWithP256AndSHA256,
-		ECDSAWithP384AndSHA384,
-		ECDSAWithP521AndSHA512:
-		pk, ok := cert.PublicKey.(*ecdsa.PublicKey)
-		if !ok {
-			return false
-		}
-
-		return ecdsa.VerifyASN1(pk, in, dc.signature)
-	case Ed25519:
-		pk, ok := cert.PublicKey.(ed25519.PublicKey)
-		if !ok {
-			return false
-		}
-
-		return ed25519.Verify(pk, in, dc.signature)
-	case PSSWithSHA256,
-		PSSWithSHA384,
-		PSSWithSHA512:
-		pk, ok := cert.PublicKey.(*rsa.PublicKey)
-		if !ok {
-			return false
-		}
-		hash := getHash(dc.algorithm)
-		return rsa.VerifyPSS(pk, hash, in, dc.signature, nil) == nil
-	default:
-		return false
-	}
-}
-
-// Marshal encodes a DelegatedCredential structure. It also sets dc.Raw to that
-// encoding.
-func (dc *DelegatedCredential) Marshal() ([]byte, error) {
-	if len(dc.signature) > dcMaxSignatureLen {
-		return nil, errors.New("tls: delegated credential is not valid")
-	}
-	if len(dc.signature) == 0 {
-		return nil, errors.New("tls: delegated credential has no signature")
-	}
-
-	raw, err := dc.cred.marshal()
-	if err != nil {
-		return nil, err
-	}
-
-	var b cryptobyte.Builder
-	b.AddBytes(raw)
-	b.AddUint16(uint16(dc.algorithm))
-	b.AddUint16(uint16(len(dc.signature)))
-	b.AddBytes(dc.signature)
-
-	dc.raw = b.BytesOrPanic()
-	return dc.raw, nil
-}
-
-// UnmarshalDelegatedCredential decodes a DelegatedCredential structure.
-func UnmarshalDelegatedCredential(raw []byte) (*DelegatedCredential, error) {
-	rawCredentialLen, err := getCredentialLen(raw)
-	if err != nil {
-		return nil, err
-	}
-
-	credential, err := unmarshalCredential(raw[:rawCredentialLen])
-	if err != nil {
-		return nil, err
-	}
-
-	raw = raw[rawCredentialLen:]
-	if len(raw) < 4 {
-		return nil, errors.New("tls: Delegated Credential is not valid")
-	}
-
-	s := cryptobyte.String(raw)
-
-	var algo uint16
-	if !s.ReadUint16(&algo) {
-		return nil, errors.New("tls: Delegated Credential is not valid")
-	}
-
-	var rawSignatureLen uint16
-	if !s.ReadUint16(&rawSignatureLen) {
-		return nil, errors.New("tls: Delegated Credential is not valid")
-	}
-
-	var sig []byte
-	if !s.ReadBytes(&sig, int(rawSignatureLen)) {
-		return nil, errors.New("tls: Delegated Credential is not valid")
-	}
-
-	return &DelegatedCredential{
-		cred:      credential,
-		algorithm: SignatureScheme(algo),
-		signature: sig,
-	}, nil
-}

+ 0 - 1094
transport/cloudflaretls/ech.go

@@ -1,1094 +0,0 @@
-// Copyright 2020 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 (
-	"context"
-	"errors"
-	"fmt"
-	"io"
-
-	"github.com/cloudflare/circl/hpke"
-	"golang.org/x/crypto/cryptobyte"
-)
-
-const (
-	// Constants for TLS operations
-	echAcceptConfLabel    = "ech accept confirmation"
-	echAcceptConfHRRLabel = "hrr ech accept confirmation"
-
-	// Constants for HPKE operations
-	echHpkeInfoSetup = "tls ech"
-
-	// When sent in the ClientHello, the first byte of the payload of the ECH
-	// extension indicates whether the message is the ClientHelloOuter or
-	// ClientHelloInner.
-	echClientHelloOuterVariant uint8 = 0
-	echClientHelloInnerVariant uint8 = 1
-)
-
-var zeros = [8]byte{}
-
-// echOfferOrGrease is called by the client after generating its ClientHello
-// message to decide if it will offer or GREASE ECH. It does neither if ECH is
-// disabled. Returns a pair of ClientHello messages, hello and helloInner. If
-// offering ECH, these are the ClienthelloOuter and ClientHelloInner
-// respectively. Otherwise, hello is the ClientHello and helloInner == nil.
-//
-// TODO(cjpatton): "[When offering ECH, the client] MUST NOT offer to resume any
-// session for TLS 1.2 and below [in ClientHelloInner]."
-func (c *Conn) echOfferOrGrease(ctx context.Context, helloBase *clientHelloMsg) (hello, helloInner *clientHelloMsg, err error) {
-	config := c.config
-
-	if !config.ECHEnabled || testingECHTriggerBypassBeforeHRR {
-		// Bypass ECH.
-		return helloBase, nil, nil
-	}
-
-	// Choose the ECHConfig to use for this connection. If none is available, or
-	// if we're not offering TLS 1.3 or above, then GREASE.
-	echConfig, err := config.echSelectConfig(ctx, helloBase.serverName)
-	if err != nil {
-		return nil, nil, fmt.Errorf("tls: ech: fetch ech config: %s", err)
-	}
-	if echConfig == nil || config.maxSupportedVersion(roleClient) < VersionTLS13 {
-		var err error
-
-		// Generate a dummy ClientECH.
-		helloBase.ech, err = echGenerateGreaseExt(config.rand())
-		if err != nil {
-			return nil, nil, fmt.Errorf("tls: ech: failed to generate grease ECH: %s", err)
-		}
-
-		// GREASE ECH.
-		c.ech.offered = false
-		c.ech.greased = true
-		helloBase.raw = nil
-		return helloBase, nil, nil
-	}
-
-	// Store the ECH config parameters that are needed later.
-	c.ech.configId = echConfig.configId
-	c.ech.maxNameLen = int(echConfig.maxNameLen)
-
-	// Generate the HPKE context. Store it in case of HRR.
-	var enc []byte
-	enc, c.ech.sealer, err = echConfig.setupSealer(config.rand())
-	if err != nil {
-		return nil, nil, fmt.Errorf("tls: ech: %s", err)
-	}
-
-	// ClientHelloInner is constructed from the base ClientHello. The payload of
-	// the "encrypted_client_hello" extension is a single 1 byte indicating that
-	// this is the ClientHelloInner.
-	helloInner = helloBase
-	helloInner.ech = []byte{echClientHelloInnerVariant}
-
-	// Ensure that only TLS 1.3 and above are offered in the inner handshake.
-	if v := helloInner.supportedVersions; len(v) == 0 || v[len(v)-1] < VersionTLS13 {
-		return nil, nil, errors.New("tls: ech: only TLS 1.3 is allowed in ClientHelloInner")
-	}
-
-	// ClientHelloOuter is constructed by generating a fresh ClientHello and
-	// copying "session_id" from ClientHelloInner, setting "server_name" to the
-	// client-facing server, and adding the "encrypted_client_hello" extension.
-	//
-	// In addition, we discard the "key_share" and instead use the one from
-	// ClientHelloInner.
-	hello, _, err = c.makeClientHello(config.MinVersion)
-	if err != nil {
-		return nil, nil, fmt.Errorf("tls: ech: %s", err)
-	}
-	hello.sessionId = helloBase.sessionId
-	hello.serverName = hostnameInSNI(string(echConfig.rawPublicName))
-	if err := c.echUpdateClientHelloOuter(hello, helloInner, enc); err != nil {
-		return nil, nil, err
-	}
-
-	// Offer ECH.
-	c.ech.offered = true
-	helloInner.raw = nil
-	hello.raw = nil
-	return hello, helloInner, nil
-}
-
-// echUpdateClientHelloOuter is called by the client to construct the payload of
-// the ECH extension in the outer handshake.
-func (c *Conn) echUpdateClientHelloOuter(hello, helloInner *clientHelloMsg, enc []byte) error {
-	var (
-		ech echClientOuter
-		err error
-	)
-
-	// Copy all compressed extensions from ClientHelloInner into
-	// ClientHelloOuter.
-	for _, ext := range echOuterExtensions() {
-		echCopyExtensionFromClientHelloInner(hello, helloInner, ext)
-	}
-
-	// Always copy the "key_shares" extension from ClientHelloInner, regardless
-	// of whether it gets compressed.
-	hello.keyShares = helloInner.keyShares
-
-	_, kdf, aead := c.ech.sealer.Suite().Params()
-	ech.handle.suite.kdfId = uint16(kdf)
-	ech.handle.suite.aeadId = uint16(aead)
-	ech.handle.configId = c.ech.configId
-	ech.handle.enc = enc
-
-	// EncodedClientHelloInner
-	helloInner.raw = nil
-	encodedHelloInner := echEncodeClientHelloInner(
-		helloInner.marshal(),
-		len(helloInner.serverName),
-		c.ech.maxNameLen)
-	if encodedHelloInner == nil {
-		return errors.New("tls: ech: encoding of EncodedClientHelloInner failed")
-	}
-
-	// ClientHelloOuterAAD
-	hello.raw = nil
-	hello.ech = ech.marshal()
-	helloOuterAad := echEncodeClientHelloOuterAAD(hello.marshal(),
-		aead.CipherLen(uint(len(encodedHelloInner))))
-	if helloOuterAad == nil {
-		return errors.New("tls: ech: encoding of ClientHelloOuterAAD failed")
-	}
-
-	ech.payload, err = c.ech.sealer.Seal(encodedHelloInner, helloOuterAad)
-	if err != nil {
-		return fmt.Errorf("tls: ech: seal failed: %s", err)
-	}
-	if testingECHTriggerPayloadDecryptError {
-		ech.payload[0] ^= 0xff // Inauthentic ciphertext
-	}
-	ech.raw = nil
-	hello.ech = ech.marshal()
-
-	helloInner.raw = nil
-	hello.raw = nil
-	return nil
-}
-
-// echAcceptOrReject is called by the client-facing server to determine whether
-// ECH was offered by the client, and if so, whether to accept or reject. The
-// return value is the ClientHello that will be used for the connection.
-//
-// This function is called prior to processing the ClientHello. In case of
-// HelloRetryRequest, it is also called before processing the second
-// ClientHello. This is indicated by the afterHRR flag.
-func (c *Conn) echAcceptOrReject(hello *clientHelloMsg, afterHRR bool) (*clientHelloMsg, error) {
-	config := c.config
-	p := config.ServerECHProvider
-
-	if !config.echCanAccept() {
-		// Bypass ECH.
-		return hello, nil
-	}
-
-	if len(hello.ech) > 0 { // The ECH extension is present
-		switch hello.ech[0] {
-		case echClientHelloInnerVariant: // inner handshake
-			if len(hello.ech) > 1 {
-				c.sendAlert(alertIllegalParameter)
-				return nil, errors.New("ech: inner handshake has non-empty payload")
-			}
-
-			// Continue as the backend server.
-			return hello, nil
-		case echClientHelloOuterVariant: // outer handshake
-		default:
-			c.sendAlert(alertIllegalParameter)
-			return nil, errors.New("ech: inner handshake has non-empty payload")
-		}
-	} else {
-		if c.ech.offered {
-			// This occurs if the server accepted prior to HRR, but the client
-			// failed to send the ECH extension in the second ClientHelloOuter. This
-			// would cause ClientHelloOuter to be used after ClientHelloInner, which
-			// is illegal.
-			c.sendAlert(alertMissingExtension)
-			return nil, errors.New("ech: hrr: bypass after offer")
-		}
-
-		// Bypass ECH.
-		return hello, nil
-	}
-
-	if afterHRR && !c.ech.offered && !c.ech.greased {
-		// The client bypassed ECH prior to HRR, but not after. This could
-		// cause ClientHelloInner to be used after ClientHelloOuter, which is
-		// illegal.
-		c.sendAlert(alertIllegalParameter)
-		return nil, errors.New("ech: hrr: offer or grease after bypass")
-	}
-
-	// Parse ClientECH.
-	ech, err := echUnmarshalClientOuter(hello.ech)
-	if err != nil {
-		c.sendAlert(alertIllegalParameter)
-		return nil, fmt.Errorf("ech: failed to parse extension: %s", err)
-	}
-
-	// Make sure that the HPKE suite and config id don't change across HRR and
-	// that the encapsulated key is not present after HRR.
-	if afterHRR && c.ech.offered {
-		_, kdf, aead := c.ech.opener.Suite().Params()
-		if ech.handle.suite.kdfId != uint16(kdf) ||
-			ech.handle.suite.aeadId != uint16(aead) ||
-			ech.handle.configId != c.ech.configId ||
-			len(ech.handle.enc) > 0 {
-			c.sendAlert(alertIllegalParameter)
-			return nil, errors.New("ech: hrr: illegal handle in second hello")
-		}
-	}
-
-	// Store the config id in case of HRR.
-	c.ech.configId = ech.handle.configId
-
-	// Ask the ECH provider for the HPKE context.
-	if c.ech.opener == nil {
-		res := p.GetDecryptionContext(ech.handle.marshal(), extensionECH)
-
-		// Compute retry configurations, skipping those indicating an
-		// unsupported version.
-		if len(res.RetryConfigs) > 0 {
-			configs, err := UnmarshalECHConfigs(res.RetryConfigs) // skips unrecognized versions
-			if err != nil {
-				c.sendAlert(alertInternalError)
-				return nil, fmt.Errorf("ech: %s", err)
-			}
-
-			if len(configs) > 0 {
-				c.ech.retryConfigs, err = echMarshalConfigs(configs)
-				if err != nil {
-					c.sendAlert(alertInternalError)
-					return nil, fmt.Errorf("ech: %s", err)
-				}
-			}
-
-			// Check if the outer SNI matches the public name of any ECH config
-			// advertised by the client-facing server. As of
-			// draft-ietf-tls-esni-10, the client is required to use the ECH
-			// config's public name as the outer SNI. Although there's no real
-			// reason for the server to enforce this, it's worth noting it when
-			// it happens.
-			pubNameMatches := false
-			for _, config := range configs {
-				if hello.serverName == string(config.rawPublicName) {
-					pubNameMatches = true
-				}
-			}
-			if !pubNameMatches {
-				c.handleCFEvent(CFEventECHPublicNameMismatch{})
-			}
-		}
-
-		switch res.Status {
-		case ECHProviderSuccess:
-			c.ech.opener, err = hpke.UnmarshalOpener(res.Context)
-			if err != nil {
-				c.sendAlert(alertInternalError)
-				return nil, fmt.Errorf("ech: %s", err)
-			}
-		case ECHProviderReject:
-			// Reject ECH. We do not know at this point whether the client
-			// intended to offer or grease ECH, so we presume grease until the
-			// client indicates rejection by sending an "ech_required" alert.
-			c.ech.greased = true
-			return hello, nil
-		case ECHProviderAbort:
-			c.sendAlert(alert(res.Alert))
-			return nil, fmt.Errorf("ech: provider aborted: %s", res.Error)
-		default:
-			c.sendAlert(alertInternalError)
-			return nil, errors.New("ech: unexpected provider status")
-		}
-	}
-
-	// ClientHelloOuterAAD
-	rawHelloOuterAad := echEncodeClientHelloOuterAAD(hello.marshal(), uint(len(ech.payload)))
-	if rawHelloOuterAad == nil {
-		// This occurs if the ClientHelloOuter is malformed. This values was
-		// already parsed into `hello`, so this should not happen.
-		c.sendAlert(alertInternalError)
-		return nil, fmt.Errorf("ech: failed to encode ClientHelloOuterAAD")
-	}
-
-	// EncodedClientHelloInner
-	rawEncodedHelloInner, err := c.ech.opener.Open(ech.payload, rawHelloOuterAad)
-	if err != nil {
-		if afterHRR && c.ech.accepted {
-			// Don't reject after accept, as this would result in processing the
-			// ClientHelloOuter after processing the ClientHelloInner.
-			c.sendAlert(alertDecryptError)
-			return nil, fmt.Errorf("ech: hrr: reject after accept: %s", err)
-		}
-
-		// Reject ECH. We do not know at this point whether the client
-		// intended to offer or grease ECH, so we presume grease until the
-		// client indicates rejection by sending an "ech_required" alert.
-		c.ech.greased = true
-		return hello, nil
-	}
-
-	// ClientHelloInner
-	rawHelloInner := echDecodeClientHelloInner(rawEncodedHelloInner, hello.marshal(), hello.sessionId)
-	if rawHelloInner == nil {
-		c.sendAlert(alertIllegalParameter)
-		return nil, fmt.Errorf("ech: failed to decode EncodedClientHelloInner")
-	}
-	helloInner := new(clientHelloMsg)
-	if !helloInner.unmarshal(rawHelloInner) {
-		c.sendAlert(alertIllegalParameter)
-		return nil, fmt.Errorf("ech: failed to parse ClientHelloInner")
-	}
-
-	// Check for a well-formed ECH extension.
-	if len(helloInner.ech) != 1 ||
-		helloInner.ech[0] != echClientHelloInnerVariant {
-		c.sendAlert(alertIllegalParameter)
-		return nil, fmt.Errorf("ech: ClientHelloInner does not have a well-formed ECH extension")
-	}
-
-	// Check that the client did not offer TLS 1.2 or below in the inner
-	// handshake.
-	helloInnerSupportsTLS12OrBelow := len(helloInner.supportedVersions) == 0
-	for _, v := range helloInner.supportedVersions {
-		if v < VersionTLS13 {
-			helloInnerSupportsTLS12OrBelow = true
-		}
-	}
-	if helloInnerSupportsTLS12OrBelow {
-		c.sendAlert(alertIllegalParameter)
-		return nil, errors.New("ech: ClientHelloInner offers TLS 1.2 or below")
-	}
-
-	// Accept ECH.
-	c.ech.offered = true
-	c.ech.accepted = true
-	return helloInner, nil
-}
-
-// echClientOuter represents a ClientECH structure, the payload of the client's
-// "encrypted_client_hello" extension that appears in the outer handshake.
-type echClientOuter struct {
-	raw []byte
-
-	// Parsed from raw
-	handle  echContextHandle
-	payload []byte
-}
-
-// echUnmarshalClientOuter parses a ClientECH structure. The caller provides the
-// ECH version indicated by the client.
-func echUnmarshalClientOuter(raw []byte) (*echClientOuter, error) {
-	s := cryptobyte.String(raw)
-	ech := new(echClientOuter)
-	ech.raw = raw
-
-	// Make sure this is the outer handshake.
-	var variant uint8
-	if !s.ReadUint8(&variant) {
-		return nil, fmt.Errorf("error parsing ClientECH.type")
-	}
-	if variant != echClientHelloOuterVariant {
-		return nil, fmt.Errorf("unexpected ClientECH.type (want outer (0))")
-	}
-
-	// Parse the context handle.
-	if !echReadContextHandle(&s, &ech.handle) {
-		return nil, fmt.Errorf("error parsing context handle")
-	}
-	endOfContextHandle := len(raw) - len(s)
-	ech.handle.raw = raw[1:endOfContextHandle]
-
-	// Parse the payload.
-	var t cryptobyte.String
-	if !s.ReadUint16LengthPrefixed(&t) ||
-		!t.ReadBytes(&ech.payload, len(t)) || !s.Empty() {
-		return nil, fmt.Errorf("error parsing payload")
-	}
-
-	return ech, nil
-}
-
-func (ech *echClientOuter) marshal() []byte {
-	if ech.raw != nil {
-		return ech.raw
-	}
-	var b cryptobyte.Builder
-	b.AddUint8(echClientHelloOuterVariant)
-	b.AddBytes(ech.handle.marshal())
-	b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-		b.AddBytes(ech.payload)
-	})
-	return b.BytesOrPanic()
-}
-
-// echContextHandle represents the prefix of a ClientECH structure used by
-// the server to compute the HPKE context.
-type echContextHandle struct {
-	raw []byte
-
-	// Parsed from raw
-	suite    hpkeSymmetricCipherSuite
-	configId uint8
-	enc      []byte
-}
-
-func (handle *echContextHandle) marshal() []byte {
-	if handle.raw != nil {
-		return handle.raw
-	}
-	var b cryptobyte.Builder
-	b.AddUint16(handle.suite.kdfId)
-	b.AddUint16(handle.suite.aeadId)
-	b.AddUint8(handle.configId)
-	b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-		b.AddBytes(handle.enc)
-	})
-	return b.BytesOrPanic()
-}
-
-func echReadContextHandle(s *cryptobyte.String, handle *echContextHandle) bool {
-	var t cryptobyte.String
-	if !s.ReadUint16(&handle.suite.kdfId) || // cipher_suite.kdf_id
-		!s.ReadUint16(&handle.suite.aeadId) || // cipher_suite.aead_id
-		!s.ReadUint8(&handle.configId) || // config_id
-		!s.ReadUint16LengthPrefixed(&t) || // enc
-		!t.ReadBytes(&handle.enc, len(t)) {
-		return false
-	}
-	return true
-}
-
-// hpkeSymmetricCipherSuite represents an ECH ciphersuite, a KDF/AEAD algorithm pair. This
-// is different from an HPKE ciphersuite, which represents a KEM/KDF/AEAD
-// triple.
-type hpkeSymmetricCipherSuite struct {
-	kdfId, aeadId uint16
-}
-
-// Generates a grease ECH extension using a hard-coded KEM public key.
-func echGenerateGreaseExt(rand io.Reader) ([]byte, error) {
-	var err error
-	dummyX25519PublicKey := []byte{
-		143, 38, 37, 36, 12, 6, 229, 30, 140, 27, 167, 73, 26, 100, 203, 107, 216,
-		81, 163, 222, 52, 211, 54, 210, 46, 37, 78, 216, 157, 97, 241, 244,
-	}
-	dummyEncodedHelloInnerLen := 100 // TODO(cjpatton): Compute this correctly.
-	kem, kdf, aead := defaultHPKESuite.Params()
-
-	pk, err := kem.Scheme().UnmarshalBinaryPublicKey(dummyX25519PublicKey)
-	if err != nil {
-		return nil, fmt.Errorf("tls: grease ech: failed to parse dummy public key: %s", err)
-	}
-	sender, err := defaultHPKESuite.NewSender(pk, nil)
-	if err != nil {
-		return nil, fmt.Errorf("tls: grease ech: failed to create sender: %s", err)
-	}
-
-	var ech echClientOuter
-	ech.handle.suite.kdfId = uint16(kdf)
-	ech.handle.suite.aeadId = uint16(aead)
-	randomByte := make([]byte, 1)
-	_, err = io.ReadFull(rand, randomByte)
-	if err != nil {
-		return nil, fmt.Errorf("tls: grease ech: %s", err)
-	}
-	ech.handle.configId = randomByte[0]
-	ech.handle.enc, _, err = sender.Setup(rand)
-	if err != nil {
-		return nil, fmt.Errorf("tls: grease ech: %s", err)
-	}
-	ech.payload = make([]byte,
-		int(aead.CipherLen(uint(dummyEncodedHelloInnerLen))))
-	if _, err = io.ReadFull(rand, ech.payload); err != nil {
-		return nil, fmt.Errorf("tls: grease ech: %s", err)
-	}
-	return ech.marshal(), nil
-}
-
-// echEncodeClientHelloInner interprets innerData as a ClientHelloInner message
-// and transforms it into an EncodedClientHelloInner. Returns nil if parsing
-// innerData fails.
-func echEncodeClientHelloInner(innerData []byte, serverNameLen, maxNameLen int) []byte {
-	var (
-		errIllegalParameter      = errors.New("illegal parameter")
-		outerExtensions          = echOuterExtensions()
-		msgType                  uint8
-		legacyVersion            uint16
-		random                   []byte
-		legacySessionId          cryptobyte.String
-		cipherSuites             cryptobyte.String
-		legacyCompressionMethods cryptobyte.String
-		extensions               cryptobyte.String
-		s                        cryptobyte.String
-		b                        cryptobyte.Builder
-	)
-
-	u := cryptobyte.String(innerData)
-	if !u.ReadUint8(&msgType) ||
-		!u.ReadUint24LengthPrefixed(&s) || !u.Empty() {
-		return nil
-	}
-
-	if !s.ReadUint16(&legacyVersion) ||
-		!s.ReadBytes(&random, 32) ||
-		!s.ReadUint8LengthPrefixed(&legacySessionId) ||
-		!s.ReadUint16LengthPrefixed(&cipherSuites) ||
-		!s.ReadUint8LengthPrefixed(&legacyCompressionMethods) {
-		return nil
-	}
-
-	if s.Empty() {
-		// Extensions field must be present in TLS 1.3.
-		return nil
-	}
-
-	if !s.ReadUint16LengthPrefixed(&extensions) || !s.Empty() {
-		return nil
-	}
-
-	b.AddUint16(legacyVersion)
-	b.AddBytes(random)
-	b.AddUint8(0) // 0-length legacy_session_id
-	b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-		b.AddBytes(cipherSuites)
-	})
-	b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
-		b.AddBytes(legacyCompressionMethods)
-	})
-	b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-		if testingECHOuterExtIncorrectOrder {
-			// Replace outer extensions with "outer_extension" extension, but in
-			// the incorrect order.
-			echAddOuterExtensions(b, outerExtensions)
-		}
-
-		for !extensions.Empty() {
-			var ext uint16
-			var extData cryptobyte.String
-			if !extensions.ReadUint16(&ext) ||
-				!extensions.ReadUint16LengthPrefixed(&extData) {
-				panic(cryptobyte.BuildError{Err: errIllegalParameter})
-			}
-
-			if len(outerExtensions) > 0 && ext == outerExtensions[0] {
-				if !testingECHOuterExtIncorrectOrder {
-					// Replace outer extensions with "outer_extension" extension.
-					echAddOuterExtensions(b, outerExtensions)
-				}
-
-				// Consume the remaining outer extensions.
-				for _, outerExt := range outerExtensions[1:] {
-					if !extensions.ReadUint16(&ext) ||
-						!extensions.ReadUint16LengthPrefixed(&extData) {
-						panic(cryptobyte.BuildError{Err: errIllegalParameter})
-					}
-					if ext != outerExt {
-						panic("internal error: malformed ClientHelloInner")
-					}
-				}
-
-			} else {
-				b.AddUint16(ext)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddBytes(extData)
-				})
-			}
-		}
-	})
-
-	encodedData, err := b.Bytes()
-	if err == errIllegalParameter {
-		return nil // Input malformed
-	} else if err != nil {
-		panic(err) // Host encountered internal error
-	}
-
-	// Add padding.
-	paddingLen := 0
-	if serverNameLen > 0 {
-		// draft-ietf-tls-esni-13, Section 6.1.3:
-		//
-		// If the ClientHelloInner contained a "server_name" extension with a
-		// name of length D, add max(0, L - D) bytes of padding.
-		if n := maxNameLen - serverNameLen; n > 0 {
-			paddingLen += n
-		}
-	} else {
-		// draft-ietf-tls-esni-13, Section 6.1.3:
-		//
-		// If the ClientHelloInner did not contain a "server_name" extension
-		// (e.g., if the client is connecting to an IP address), add L + 9 bytes
-		// of padding.  This is the length of a "server_name" extension with an
-		// L-byte name.
-		const sniPaddingLen = 9
-		paddingLen += sniPaddingLen + maxNameLen
-	}
-	paddingLen = 31 - ((len(encodedData) + paddingLen - 1) % 32)
-	for i := 0; i < paddingLen; i++ {
-		encodedData = append(encodedData, 0)
-	}
-
-	return encodedData
-}
-
-func echAddOuterExtensions(b *cryptobyte.Builder, outerExtensions []uint16) {
-	b.AddUint16(extensionECHOuterExtensions)
-	b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-		b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
-			for _, outerExt := range outerExtensions {
-				b.AddUint16(outerExt)
-			}
-			if testingECHOuterExtIllegal {
-				// This is not allowed.
-				b.AddUint16(extensionECH)
-			}
-		})
-	})
-}
-
-// echDecodeClientHelloInner interprets encodedData as an EncodedClientHelloInner
-// message and substitutes the "outer_extension" extension with extensions from
-// outerData, interpreted as the ClientHelloOuter message. Returns nil if
-// parsing encodedData fails.
-func echDecodeClientHelloInner(encodedData, outerData, outerSessionId []byte) []byte {
-	var (
-		errIllegalParameter      = errors.New("illegal parameter")
-		legacyVersion            uint16
-		random                   []byte
-		legacySessionId          cryptobyte.String
-		cipherSuites             cryptobyte.String
-		legacyCompressionMethods cryptobyte.String
-		extensions               cryptobyte.String
-		b                        cryptobyte.Builder
-	)
-
-	s := cryptobyte.String(encodedData)
-	if !s.ReadUint16(&legacyVersion) ||
-		!s.ReadBytes(&random, 32) ||
-		!s.ReadUint8LengthPrefixed(&legacySessionId) ||
-		!s.ReadUint16LengthPrefixed(&cipherSuites) ||
-		!s.ReadUint8LengthPrefixed(&legacyCompressionMethods) {
-		return nil
-	}
-
-	if len(legacySessionId) > 0 {
-		return nil
-	}
-
-	if s.Empty() {
-		// Extensions field must be present in TLS 1.3.
-		return nil
-	}
-
-	if !s.ReadUint16LengthPrefixed(&extensions) {
-		return nil
-	}
-
-	b.AddUint8(typeClientHello)
-	b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
-		b.AddUint16(legacyVersion)
-		b.AddBytes(random)
-		b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
-			b.AddBytes(outerSessionId) // ClientHelloOuter.legacy_session_id
-		})
-		b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-			b.AddBytes(cipherSuites)
-		})
-		b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
-			b.AddBytes(legacyCompressionMethods)
-		})
-		b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-			var handledOuterExtensions bool
-			for !extensions.Empty() {
-				var ext uint16
-				var extData cryptobyte.String
-				if !extensions.ReadUint16(&ext) ||
-					!extensions.ReadUint16LengthPrefixed(&extData) {
-					panic(cryptobyte.BuildError{Err: errIllegalParameter})
-				}
-
-				if ext == extensionECHOuterExtensions {
-					if handledOuterExtensions {
-						// It is an error to send any extension more than once in a
-						// single message.
-						panic(cryptobyte.BuildError{Err: errIllegalParameter})
-					}
-					handledOuterExtensions = true
-
-					// Read the referenced outer extensions.
-					referencedExts := make([]uint16, 0, 10)
-					var outerExtData cryptobyte.String
-					if !extData.ReadUint8LengthPrefixed(&outerExtData) ||
-						len(outerExtData)%2 != 0 ||
-						!extData.Empty() {
-						panic(cryptobyte.BuildError{Err: errIllegalParameter})
-					}
-					for !outerExtData.Empty() {
-						if !outerExtData.ReadUint16(&ext) ||
-							ext == extensionECH {
-							panic(cryptobyte.BuildError{Err: errIllegalParameter})
-						}
-						referencedExts = append(referencedExts, ext)
-					}
-
-					// Add the outer extensions from the ClientHelloOuter into the
-					// ClientHelloInner.
-					outerCt := 0
-					r := processClientHelloExtensions(outerData, func(ext uint16, extData cryptobyte.String) bool {
-						if outerCt < len(referencedExts) && ext == referencedExts[outerCt] {
-							outerCt++
-							b.AddUint16(ext)
-							b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-								b.AddBytes(extData)
-							})
-						}
-						return true
-					})
-
-					// Ensure that all outer extensions have been incorporated
-					// exactly once, and in the correct order.
-					if !r || outerCt != len(referencedExts) {
-						panic(cryptobyte.BuildError{Err: errIllegalParameter})
-					}
-				} else {
-					b.AddUint16(ext)
-					b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-						b.AddBytes(extData)
-					})
-				}
-			}
-		})
-	})
-
-	innerData, err := b.Bytes()
-	if err == errIllegalParameter {
-		return nil // Input malformed
-	} else if err != nil {
-		panic(err) // Host encountered internal error
-	}
-
-	// Read the padding.
-	for !s.Empty() {
-		var zero uint8
-		if !s.ReadUint8(&zero) || zero != 0 {
-			return nil
-		}
-	}
-
-	return innerData
-}
-
-// echEncodeClientHelloOuterAAD interprets outerData as ClientHelloOuter and
-// constructs a ClientHelloOuterAAD. The output doesn't have the 4-byte prefix
-// that indicates the handshake message type and its length.
-func echEncodeClientHelloOuterAAD(outerData []byte, payloadLen uint) []byte {
-	var (
-		errIllegalParameter      = errors.New("illegal parameter")
-		msgType                  uint8
-		legacyVersion            uint16
-		random                   []byte
-		legacySessionId          cryptobyte.String
-		cipherSuites             cryptobyte.String
-		legacyCompressionMethods cryptobyte.String
-		extensions               cryptobyte.String
-		s                        cryptobyte.String
-		b                        cryptobyte.Builder
-	)
-
-	u := cryptobyte.String(outerData)
-	if !u.ReadUint8(&msgType) ||
-		!u.ReadUint24LengthPrefixed(&s) || !u.Empty() {
-		return nil
-	}
-
-	if !s.ReadUint16(&legacyVersion) ||
-		!s.ReadBytes(&random, 32) ||
-		!s.ReadUint8LengthPrefixed(&legacySessionId) ||
-		!s.ReadUint16LengthPrefixed(&cipherSuites) ||
-		!s.ReadUint8LengthPrefixed(&legacyCompressionMethods) {
-		return nil
-	}
-
-	if s.Empty() {
-		// Extensions field must be present in TLS 1.3.
-		return nil
-	}
-
-	if !s.ReadUint16LengthPrefixed(&extensions) || !s.Empty() {
-		return nil
-	}
-
-	b.AddUint16(legacyVersion)
-	b.AddBytes(random)
-	b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
-		b.AddBytes(legacySessionId)
-	})
-	b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-		b.AddBytes(cipherSuites)
-	})
-	b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
-		b.AddBytes(legacyCompressionMethods)
-	})
-	b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-		for !extensions.Empty() {
-			var ext uint16
-			var extData cryptobyte.String
-			if !extensions.ReadUint16(&ext) ||
-				!extensions.ReadUint16LengthPrefixed(&extData) {
-				panic(cryptobyte.BuildError{Err: errIllegalParameter})
-			}
-
-			// If this is the ECH extension and the payload is the outer variant
-			// of ClientECH, then replace the payloadLen 0 bytes.
-			if ext == extensionECH {
-				ech, err := echUnmarshalClientOuter(extData)
-				if err != nil {
-					panic(cryptobyte.BuildError{Err: errIllegalParameter})
-				}
-				ech.payload = make([]byte, payloadLen)
-				ech.raw = nil
-				extData = ech.marshal()
-			}
-
-			b.AddUint16(ext)
-			b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-				b.AddBytes(extData)
-			})
-		}
-	})
-
-	outerAadData, err := b.Bytes()
-	if err == errIllegalParameter {
-		return nil // Input malformed
-	} else if err != nil {
-		panic(err) // Host encountered internal error
-	}
-
-	return outerAadData
-}
-
-// echEncodeAcceptConfHelloRetryRequest interprets data as a ServerHello message
-// and replaces the payload of the ECH extension with 8 zero bytes. The output
-// includes the 4-byte prefix that indicates the message type and its length.
-func echEncodeAcceptConfHelloRetryRequest(data []byte) []byte {
-	var (
-		errIllegalParameter = errors.New("illegal parameter")
-		vers                uint16
-		random              []byte
-		sessionId           []byte
-		cipherSuite         uint16
-		compressionMethod   uint8
-		s                   cryptobyte.String
-		b                   cryptobyte.Builder
-	)
-
-	s = cryptobyte.String(data)
-	if !s.Skip(4) || // message type and uint24 length field
-		!s.ReadUint16(&vers) || !s.ReadBytes(&random, 32) ||
-		!readUint8LengthPrefixed(&s, &sessionId) ||
-		!s.ReadUint16(&cipherSuite) ||
-		!s.ReadUint8(&compressionMethod) {
-		return nil
-	}
-
-	if s.Empty() {
-		// ServerHello is optionally followed by extension data
-		return nil
-	}
-
-	var extensions cryptobyte.String
-	if !s.ReadUint16LengthPrefixed(&extensions) || !s.Empty() {
-		return nil
-	}
-
-	b.AddUint8(typeServerHello)
-	b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
-		b.AddUint16(vers)
-		b.AddBytes(random)
-		b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
-			b.AddBytes(sessionId)
-		})
-		b.AddUint16(cipherSuite)
-		b.AddUint8(compressionMethod)
-		b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-			for !extensions.Empty() {
-				var extension uint16
-				var extData cryptobyte.String
-				if !extensions.ReadUint16(&extension) ||
-					!extensions.ReadUint16LengthPrefixed(&extData) {
-					panic(cryptobyte.BuildError{Err: errIllegalParameter})
-				}
-
-				b.AddUint16(extension)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					if extension == extensionECH {
-						b.AddBytes(zeros[:8])
-					} else {
-						b.AddBytes(extData)
-					}
-				})
-			}
-		})
-	})
-
-	encodedData, err := b.Bytes()
-	if err == errIllegalParameter {
-		return nil // Input malformed
-	} else if err != nil {
-		panic(err) // Host encountered internal error
-	}
-
-	return encodedData
-}
-
-// processClientHelloExtensions interprets data as a ClientHello and applies a
-// function proc to each extension. Returns a bool indicating whether parsing
-// succeeded.
-func processClientHelloExtensions(data []byte, proc func(ext uint16, extData cryptobyte.String) bool) bool {
-	_, extensionsData := splitClientHelloExtensions(data)
-	if extensionsData == nil {
-		return false
-	}
-
-	s := cryptobyte.String(extensionsData)
-	if s.Empty() {
-		// Extensions field not present.
-		return true
-	}
-
-	var extensions cryptobyte.String
-	if !s.ReadUint16LengthPrefixed(&extensions) || !s.Empty() {
-		return false
-	}
-
-	for !extensions.Empty() {
-		var ext uint16
-		var extData cryptobyte.String
-		if !extensions.ReadUint16(&ext) ||
-			!extensions.ReadUint16LengthPrefixed(&extData) {
-			return false
-		}
-		if ok := proc(ext, extData); !ok {
-			return false
-		}
-	}
-	return true
-}
-
-// splitClientHelloExtensions interprets data as a ClientHello message and
-// returns two strings: the first contains the start of the ClientHello up to
-// the start of the extensions; and the second is the length-prefixed
-// extensions. Returns (nil, nil) if parsing of data fails.
-func splitClientHelloExtensions(data []byte) ([]byte, []byte) {
-	s := cryptobyte.String(data)
-
-	var ignored uint16
-	var t cryptobyte.String
-	if !s.Skip(4) || // message type and uint24 length field
-		!s.ReadUint16(&ignored) || !s.Skip(32) || // vers, random
-		!s.ReadUint8LengthPrefixed(&t) { // session_id
-		return nil, nil
-	}
-
-	if !s.ReadUint16LengthPrefixed(&t) { // cipher_suites
-		return nil, nil
-	}
-
-	if !s.ReadUint8LengthPrefixed(&t) { // compression_methods
-		return nil, nil
-	}
-
-	return data[:len(data)-len(s)], s
-}
-
-// TODO(cjpatton): Handle public name as described in draft-ietf-tls-esni-13,
-// Section 4.
-//
-// TODO(cjpatton): Implement ECH config extensions as described in
-// draft-ietf-tls-esni-13, Section 4.1.
-func (c *Config) echSelectConfig(ctx context.Context, serverName string) (*ECHConfig, error) {
-	for _, echConfig := range c.ClientECHConfigs {
-		if _, err := echConfig.selectSuite(); err == nil &&
-			echConfig.version == extensionECH {
-			return &echConfig, nil
-		}
-	}
-	if c.GetClientECHConfigs != nil {
-		echConfigs, err := c.GetClientECHConfigs(ctx, serverName)
-		if err != nil {
-			return nil, err
-		}
-		for _, echConfig := range echConfigs {
-			if _, err = echConfig.selectSuite(); err == nil &&
-				echConfig.version == extensionECH {
-				return &echConfig, nil
-			}
-		}
-	}
-	return nil, nil
-}
-
-func (c *Config) echCanOffer() bool {
-	if c == nil {
-		return false
-	}
-	return c.ECHEnabled &&
-		c.maxSupportedVersion(roleClient) >= VersionTLS13
-}
-
-func (c *Config) echCanAccept() bool {
-	if c == nil {
-		return false
-	}
-	return c.ECHEnabled &&
-		c.ServerECHProvider != nil &&
-		c.maxSupportedVersion(roleServer) >= VersionTLS13
-}
-
-// echOuterExtensions returns the list of extensions of the ClientHelloOuter
-// that will be incorporated into the CleintHelloInner.
-func echOuterExtensions() []uint16 {
-	// NOTE(cjpatton): It would be nice to incorporate more extensions, but
-	// "key_share" is the last extension to appear in the ClientHello before
-	// "pre_shared_key". As a result, the only contiguous sequence of outer
-	// extensions that contains "key_share" is "key_share" itself. Note that
-	// we cannot change the order of extensions in the ClientHello, as the
-	// unit tests expect "key_share" to be the second to last extension.
-	outerExtensions := []uint16{extensionKeyShare}
-	if testingECHOuterExtMany {
-		// NOTE(cjpatton): Incorporating this particular sequence does not
-		// yield significant savings. However, it's useful to test that our
-		// server correctly handles a sequence of compressed extensions and
-		// not just one.
-		outerExtensions = []uint16{
-			extensionStatusRequest,
-			extensionSupportedCurves,
-			extensionSupportedPoints,
-		}
-	} else if testingECHOuterExtNone {
-		outerExtensions = []uint16{}
-	}
-
-	return outerExtensions
-}
-
-func echCopyExtensionFromClientHelloInner(hello, helloInner *clientHelloMsg, ext uint16) {
-	switch ext {
-	case extensionStatusRequest:
-		hello.ocspStapling = helloInner.ocspStapling
-	case extensionSupportedCurves:
-		hello.supportedCurves = helloInner.supportedCurves
-	case extensionSupportedPoints:
-		hello.supportedPoints = helloInner.supportedPoints
-	case extensionKeyShare:
-		hello.keyShares = helloInner.keyShares
-	default:
-		panic(fmt.Errorf("tried to copy unrecognized extension: %04x", ext))
-	}
-}

+ 0 - 164
transport/cloudflaretls/ech_config.go

@@ -1,164 +0,0 @@
-// Copyright 2020 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 (
-	"errors"
-	"fmt"
-	"io"
-
-	"github.com/cloudflare/circl/hpke"
-	"github.com/cloudflare/circl/kem"
-	"golang.org/x/crypto/cryptobyte"
-)
-
-// ECHConfig represents an ECH configuration.
-type ECHConfig struct {
-	pk  kem.PublicKey
-	raw []byte
-
-	// Parsed from raw
-	version           uint16
-	configId          uint8
-	rawPublicName     []byte
-	rawPublicKey      []byte
-	kemId             uint16
-	suites            []hpkeSymmetricCipherSuite
-	maxNameLen        uint8
-	ignoredExtensions []byte
-}
-
-// UnmarshalECHConfigs parses a sequence of ECH configurations.
-func UnmarshalECHConfigs(raw []byte) ([]ECHConfig, error) {
-	var (
-		err         error
-		config      ECHConfig
-		t, contents cryptobyte.String
-	)
-	configs := make([]ECHConfig, 0)
-	s := cryptobyte.String(raw)
-	if !s.ReadUint16LengthPrefixed(&t) || !s.Empty() {
-		return configs, errors.New("error parsing configs")
-	}
-	raw = raw[2:]
-ConfigsLoop:
-	for !t.Empty() {
-		l := len(t)
-		if !t.ReadUint16(&config.version) ||
-			!t.ReadUint16LengthPrefixed(&contents) {
-			return nil, errors.New("error parsing config")
-		}
-		n := l - len(t)
-		config.raw = raw[:n]
-		raw = raw[n:]
-
-		if config.version != extensionECH {
-			continue ConfigsLoop
-		}
-		if !readConfigContents(&contents, &config) {
-			return nil, errors.New("error parsing config contents")
-		}
-
-		kem := hpke.KEM(config.kemId)
-		if !kem.IsValid() {
-			continue ConfigsLoop
-		}
-		config.pk, err = kem.Scheme().UnmarshalBinaryPublicKey(config.rawPublicKey)
-		if err != nil {
-			return nil, fmt.Errorf("error parsing public key: %s", err)
-		}
-		configs = append(configs, config)
-	}
-	return configs, nil
-}
-
-func echMarshalConfigs(configs []ECHConfig) ([]byte, error) {
-	var b cryptobyte.Builder
-	b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-		for _, config := range configs {
-			if config.raw == nil {
-				panic("config.raw not set")
-			}
-			b.AddBytes(config.raw)
-		}
-	})
-	return b.Bytes()
-}
-
-func readConfigContents(contents *cryptobyte.String, config *ECHConfig) bool {
-	var t cryptobyte.String
-	if !contents.ReadUint8(&config.configId) ||
-		!contents.ReadUint16(&config.kemId) ||
-		!contents.ReadUint16LengthPrefixed(&t) ||
-		!t.ReadBytes(&config.rawPublicKey, len(t)) ||
-		!contents.ReadUint16LengthPrefixed(&t) ||
-		len(t)%4 != 0 {
-		return false
-	}
-
-	config.suites = nil
-	for !t.Empty() {
-		var kdfId, aeadId uint16
-		if !t.ReadUint16(&kdfId) || !t.ReadUint16(&aeadId) {
-			// This indicates an internal bug.
-			panic("internal error while parsing contents.cipher_suites")
-		}
-		config.suites = append(config.suites, hpkeSymmetricCipherSuite{kdfId, aeadId})
-	}
-
-	if !contents.ReadUint8(&config.maxNameLen) ||
-		!contents.ReadUint8LengthPrefixed(&t) ||
-		!t.ReadBytes(&config.rawPublicName, len(t)) ||
-		!contents.ReadUint16LengthPrefixed(&t) ||
-		!t.ReadBytes(&config.ignoredExtensions, len(t)) ||
-		!contents.Empty() {
-		return false
-	}
-	return true
-}
-
-// setupSealer generates the client's HPKE context for use with the ECH
-// extension. It returns the context and corresponding encapsulated key.
-func (config *ECHConfig) setupSealer(rand io.Reader) (enc []byte, sealer hpke.Sealer, err error) {
-	if config.raw == nil {
-		panic("config.raw not set")
-	}
-	hpkeSuite, err := config.selectSuite()
-	if err != nil {
-		return nil, nil, err
-	}
-	info := append(append([]byte(echHpkeInfoSetup), 0), config.raw...)
-	sender, err := hpkeSuite.NewSender(config.pk, info)
-	if err != nil {
-		return nil, nil, err
-	}
-	return sender.Setup(rand)
-}
-
-// isPeerCipherSuiteSupported returns true if this configuration indicates
-// support for the given ciphersuite.
-func (config *ECHConfig) isPeerCipherSuiteSupported(suite hpkeSymmetricCipherSuite) bool {
-	for _, configSuite := range config.suites {
-		if suite == configSuite {
-			return true
-		}
-	}
-	return false
-}
-
-// selectSuite returns the first ciphersuite indicated by this
-// configuration that is supported by the caller.
-func (config *ECHConfig) selectSuite() (hpke.Suite, error) {
-	for _, suite := range config.suites {
-		hpkeSuite, err := hpkeAssembleSuite(
-			config.kemId,
-			suite.kdfId,
-			suite.aeadId,
-		)
-		if err == nil {
-			return hpkeSuite, nil
-		}
-	}
-	return hpke.Suite{}, errors.New("could not negotiate a ciphersuite")
-}

+ 0 - 302
transport/cloudflaretls/ech_provider.go

@@ -1,302 +0,0 @@
-// Copyright 2020 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 (
-	"errors"
-	"fmt"
-
-	"github.com/cloudflare/circl/hpke"
-	"github.com/cloudflare/circl/kem"
-	"golang.org/x/crypto/cryptobyte"
-)
-
-// ECHProvider specifies the interface of an ECH service provider that decrypts
-// the ECH payload on behalf of the client-facing server. It also defines the
-// set of acceptable ECH configurations.
-type ECHProvider interface {
-	// GetDecryptionContext attempts to construct the HPKE context used by the
-	// client-facing server for decryption. (See draft-irtf-cfrg-hpke-07,
-	// Section 5.2.)
-	//
-	// handle encodes the parameters of the client's "encrypted_client_hello"
-	// extension that are needed to construct the context. Since
-	// draft-ietf-tls-esni-10 these are the ECH cipher suite, the identity of
-	// the ECH configuration, and the encapsulated key.
-	//
-	// version is the version of ECH indicated by the client.
-	//
-	// res.Status == ECHProviderStatusSuccess indicates the call was successful
-	// and the caller may proceed. res.Context is set.
-	//
-	// res.Status == ECHProviderStatusReject indicates the caller must reject
-	// ECH. res.RetryConfigs may be set.
-	//
-	// res.Status == ECHProviderStatusAbort indicates the caller should abort
-	// the handshake.  Note that, in some cases, it's appropriate to reject
-	// rather than abort. In particular, aborting with "illegal_parameter" might
-	// "stick out". res.Alert and res.Error are set.
-	GetDecryptionContext(handle []byte, version uint16) (res ECHProviderResult)
-}
-
-// ECHProviderStatus is the status of the ECH provider's response.
-type ECHProviderStatus uint
-
-const (
-	ECHProviderSuccess ECHProviderStatus = 0
-	ECHProviderReject                    = 1
-	ECHProviderAbort                     = 2
-
-	errHPKEInvalidPublicKey = "hpke: invalid KEM public key"
-)
-
-// ECHProviderResult represents the result of invoking the ECH provider.
-type ECHProviderResult struct {
-	Status ECHProviderStatus
-
-	// Alert is the TLS alert sent by the caller when aborting the handshake.
-	Alert uint8
-
-	// Error is the error propagated by the caller when aborting the handshake.
-	Error error
-
-	// RetryConfigs is the sequence of ECH configs to offer to the client for
-	// retrying the handshake. This may be set in case of success or rejection.
-	RetryConfigs []byte
-
-	// Context is the server's HPKE context. This is set if ECH is not rejected
-	// by the provider and no error was reported. The data has the following
-	// format (in TLS syntax):
-	//
-	// enum { sealer(0), opener(1) } HpkeRole;
-	//
-	// struct {
-	//     HpkeRole role;
-	//     HpkeKemId kem_id;   // as defined in draft-irtf-cfrg-hpke-07
-	//     HpkeKdfId kdf_id;   // as defined in draft-irtf-cfrg-hpke-07
-	//     HpkeAeadId aead_id; // as defined in draft-irtf-cfrg-hpke-07
-	//     opaque exporter_secret<0..255>;
-	//     opaque key<0..255>;
-	//     opaque base_nonce<0..255>;
-	//     opaque seq<0..255>;
-	// } HpkeContext;
-	Context []byte
-}
-
-// EXP_ECHKeySet implements the ECHProvider interface for a sequence of ECH keys.
-//
-// NOTE: This API is EXPERIMENTAL and subject to change.
-type EXP_ECHKeySet struct {
-	// The serialized ECHConfigs, in order of the server's preference.
-	configs []byte
-
-	// Maps a configuration identifier to its secret key.
-	sk map[uint8]EXP_ECHKey
-}
-
-// EXP_NewECHKeySet constructs an EXP_ECHKeySet.
-func EXP_NewECHKeySet(keys []EXP_ECHKey) (*EXP_ECHKeySet, error) {
-	if len(keys) > 255 {
-		return nil, fmt.Errorf("tls: ech provider: unable to support more than 255 ECH configurations at once")
-	}
-
-	keySet := new(EXP_ECHKeySet)
-	keySet.sk = make(map[uint8]EXP_ECHKey)
-	configs := make([]byte, 0)
-	for _, key := range keys {
-		if _, ok := keySet.sk[key.config.configId]; ok {
-			return nil, fmt.Errorf("tls: ech provider: ECH config conflict for configId %d", key.config.configId)
-		}
-
-		keySet.sk[key.config.configId] = key
-		configs = append(configs, key.config.raw...)
-	}
-
-	var b cryptobyte.Builder
-	b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-		b.AddBytes(configs)
-	})
-	keySet.configs = b.BytesOrPanic()
-
-	return keySet, nil
-}
-
-// GetDecryptionContext is required by the ECHProvider interface.
-func (keySet *EXP_ECHKeySet) GetDecryptionContext(rawHandle []byte, version uint16) (res ECHProviderResult) {
-	// Propagate retry configurations regardless of the result. The caller sends
-	// these to the clients only if it rejects.
-	res.RetryConfigs = keySet.configs
-
-	// Ensure we know how to proceed, i.e., the caller has indicated a supported
-	// version of ECH. Currently only draft-ietf-tls-esni-13 is supported.
-	if version != extensionECH {
-		res.Status = ECHProviderAbort
-		res.Alert = uint8(alertInternalError)
-		res.Error = errors.New("version not supported")
-		return // Abort
-	}
-
-	// Parse the handle.
-	s := cryptobyte.String(rawHandle)
-	handle := new(echContextHandle)
-	if !echReadContextHandle(&s, handle) || !s.Empty() {
-		// This is the result of a client-side error. However, aborting with
-		// "illegal_parameter" would stick out, so we reject instead.
-		res.Status = ECHProviderReject
-		res.RetryConfigs = keySet.configs
-		return // Reject
-	}
-	handle.raw = rawHandle
-
-	// Look up the secret key for the configuration indicated by the client.
-	key, ok := keySet.sk[handle.configId]
-	if !ok {
-		res.Status = ECHProviderReject
-		res.RetryConfigs = keySet.configs
-		return // Reject
-	}
-
-	// Ensure that support for the selected ciphersuite is indicated by the
-	// configuration.
-	suite := handle.suite
-	if !key.config.isPeerCipherSuiteSupported(suite) {
-		// This is the result of a client-side error. However, aborting with
-		// "illegal_parameter" would stick out, so we reject instead.
-		res.Status = ECHProviderReject
-		res.RetryConfigs = keySet.configs
-		return // Reject
-	}
-
-	// Ensure the version indicated by the client matches the version supported
-	// by the configuration.
-	if version != key.config.version {
-		// This is the result of a client-side error. However, aborting with
-		// "illegal_parameter" would stick out, so we reject instead.
-		res.Status = ECHProviderReject
-		res.RetryConfigs = keySet.configs
-		return // Reject
-	}
-
-	// Compute the decryption context.
-	opener, err := key.setupOpener(handle.enc, suite)
-	if err != nil {
-		if err.Error() == errHPKEInvalidPublicKey {
-			// This occurs if the KEM algorithm used to generate handle.enc is
-			// not the same as the KEM algorithm of the key. One way this can
-			// happen is if the client sent a GREASE ECH extension with a
-			// config_id that happens to match a known config, but which uses a
-			// different KEM algorithm.
-			res.Status = ECHProviderReject
-			res.RetryConfigs = keySet.configs
-			return // Reject
-		}
-
-		res.Status = ECHProviderAbort
-		res.Alert = uint8(alertInternalError)
-		res.Error = err
-		return // Abort
-	}
-
-	// Serialize the decryption context.
-	res.Context, err = opener.MarshalBinary()
-	if err != nil {
-		res.Status = ECHProviderAbort
-		res.Alert = uint8(alertInternalError)
-		res.Error = err
-		return // Abort
-	}
-
-	res.Status = ECHProviderSuccess
-	return // Success
-}
-
-// EXP_ECHKey represents an ECH key and its corresponding configuration. The
-// encoding of an ECH Key has the format defined below (in TLS syntax). Note
-// that the ECH standard does not specify this format.
-//
-//	struct {
-//	    opaque sk<0..2^16-1>;
-//	    ECHConfig config<0..2^16>; // draft-ietf-tls-esni-13
-//	} ECHKey;
-type EXP_ECHKey struct {
-	sk     kem.PrivateKey
-	config ECHConfig
-}
-
-// EXP_UnmarshalECHKeys parses a sequence of ECH keys.
-func EXP_UnmarshalECHKeys(raw []byte) ([]EXP_ECHKey, error) {
-	var (
-		err                  error
-		key                  EXP_ECHKey
-		sk, config, contents cryptobyte.String
-	)
-	s := cryptobyte.String(raw)
-	keys := make([]EXP_ECHKey, 0)
-KeysLoop:
-	for !s.Empty() {
-		if !s.ReadUint16LengthPrefixed(&sk) ||
-			!s.ReadUint16LengthPrefixed(&config) {
-			return nil, errors.New("error parsing key")
-		}
-
-		key.config.raw = config
-		if !config.ReadUint16(&key.config.version) ||
-			!config.ReadUint16LengthPrefixed(&contents) ||
-			!config.Empty() {
-			return nil, errors.New("error parsing config")
-		}
-
-		if key.config.version != extensionECH {
-			continue KeysLoop
-		}
-		if !readConfigContents(&contents, &key.config) {
-			return nil, errors.New("error parsing config contents")
-		}
-
-		for _, suite := range key.config.suites {
-			if !hpke.KDF(suite.kdfId).IsValid() ||
-				!hpke.AEAD(suite.aeadId).IsValid() {
-				continue KeysLoop
-			}
-		}
-
-		kem := hpke.KEM(key.config.kemId)
-		if !kem.IsValid() {
-			continue KeysLoop
-		}
-		key.config.pk, err = kem.Scheme().UnmarshalBinaryPublicKey(key.config.rawPublicKey)
-		if err != nil {
-			return nil, fmt.Errorf("error parsing public key: %s", err)
-		}
-		key.sk, err = kem.Scheme().UnmarshalBinaryPrivateKey(sk)
-		if err != nil {
-			return nil, fmt.Errorf("error parsing secret key: %s", err)
-		}
-
-		keys = append(keys, key)
-	}
-	return keys, nil
-}
-
-// setupOpener computes the HPKE context used by the server in the ECH
-// extension.i
-func (key *EXP_ECHKey) setupOpener(enc []byte, suite hpkeSymmetricCipherSuite) (hpke.Opener, error) {
-	if key.config.raw == nil {
-		panic("raw config not set")
-	}
-	hpkeSuite, err := hpkeAssembleSuite(
-		key.config.kemId,
-		suite.kdfId,
-		suite.aeadId,
-	)
-	if err != nil {
-		return nil, err
-	}
-	info := append(append([]byte(echHpkeInfoSetup), 0), key.config.raw...)
-	receiver, err := hpkeSuite.NewReceiver(key.sk, info)
-	if err != nil {
-		return nil, err
-	}
-	return receiver.Setup(enc)
-}

+ 0 - 194
transport/cloudflaretls/generate_cert.go

@@ -1,194 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build ignore
-
-// Generate a self-signed X.509 certificate for a TLS server. Outputs to
-// 'cert.pem' and 'key.pem' and will overwrite existing files.
-
-package main
-
-import (
-	"crypto/ecdsa"
-	"crypto/ed25519"
-	"crypto/elliptic"
-	"crypto/rand"
-	"crypto/rsa"
-	"crypto/x509"
-	"crypto/x509/pkix"
-	"encoding/pem"
-	"flag"
-	"log"
-	"math/big"
-	"net"
-	"os"
-	"strings"
-	"time"
-
-	circlSign "github.com/cloudflare/circl/sign"
-	circlSchemes "github.com/cloudflare/circl/sign/schemes"
-)
-
-var (
-	host       = flag.String("host", "", "Comma-separated hostnames and IPs to generate a certificate for")
-	validFrom  = flag.String("start-date", "", "Creation date formatted as Jan 1 15:04:05 2011")
-	validFor   = flag.Duration("duration", 365*24*time.Hour, "Duration that certificate is valid for")
-	isCA       = flag.Bool("ca", false, "whether this cert should be its own Certificate Authority")
-	allowDC    = flag.Bool("allowDC", false, "whether this cert can be used with Delegated Credentials")
-	rsaBits    = flag.Int("rsa-bits", 2048, "Size of RSA key to generate. Ignored if --ecdsa-curve is set")
-	ecdsaCurve = flag.String("ecdsa-curve", "", "ECDSA curve to use to generate a key. Valid values are P224, P256 (recommended), P384, P521")
-	ed25519Key = flag.Bool("ed25519", false, "Generate an Ed25519 key")
-	circlKey   = flag.String("github.com/cloudflare/circl", "", "Generate a key supported by Circl")
-)
-
-func publicKey(priv any) any {
-	switch k := priv.(type) {
-	case *rsa.PrivateKey:
-		return &k.PublicKey
-	case *ecdsa.PrivateKey:
-		return &k.PublicKey
-	case ed25519.PrivateKey:
-		return k.Public().(ed25519.PublicKey)
-	case circlSign.PrivateKey:
-		return k.Public()
-	default:
-		return nil
-	}
-}
-
-func main() {
-	flag.Parse()
-
-	if len(*host) == 0 {
-		log.Fatalf("Missing required --host parameter")
-	}
-
-	var priv any
-	var err error
-	switch *ecdsaCurve {
-	case "":
-		if *ed25519Key {
-			_, priv, err = ed25519.GenerateKey(rand.Reader)
-		} else if *circlKey != "" {
-			scheme := circlSchemes.ByName(*circlKey)
-			if scheme == nil {
-				log.Fatalf("No such Circl scheme: %s", *circlKey)
-			}
-			_, priv, err = scheme.GenerateKey()
-		} else {
-			priv, err = rsa.GenerateKey(rand.Reader, *rsaBits)
-		}
-	case "P224":
-		priv, err = ecdsa.GenerateKey(elliptic.P224(), rand.Reader)
-	case "P256":
-		priv, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
-	case "P384":
-		priv, err = ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
-	case "P521":
-		priv, err = ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
-	default:
-		log.Fatalf("Unrecognized elliptic curve: %q", *ecdsaCurve)
-	}
-	if err != nil {
-		log.Fatalf("Failed to generate private key: %v", err)
-	}
-
-	// ECDSA, ED25519 and RSA subject keys should have the DigitalSignature
-	// KeyUsage bits set in the x509.Certificate template
-	keyUsage := x509.KeyUsageDigitalSignature
-	// Only RSA subject keys should have the KeyEncipherment KeyUsage bits set. In
-	// the context of TLS this KeyUsage is particular to RSA key exchange and
-	// authentication.
-	if _, isRSA := priv.(*rsa.PrivateKey); isRSA {
-		keyUsage |= x509.KeyUsageKeyEncipherment
-	}
-
-	var notBefore time.Time
-	if len(*validFrom) == 0 {
-		notBefore = time.Now()
-	} else {
-		notBefore, err = time.Parse("Jan 2 15:04:05 2006", *validFrom)
-		if err != nil {
-			log.Fatalf("Failed to parse creation date: %v", err)
-		}
-	}
-
-	notAfter := notBefore.Add(*validFor)
-
-	serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
-	serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
-	if err != nil {
-		log.Fatalf("Failed to generate serial number: %v", err)
-	}
-
-	template := x509.Certificate{
-		SerialNumber: serialNumber,
-		Subject: pkix.Name{
-			Organization: []string{"Acme Co"},
-		},
-		NotBefore: notBefore,
-		NotAfter:  notAfter,
-
-		KeyUsage:              keyUsage,
-		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
-		BasicConstraintsValid: true,
-	}
-
-	hosts := strings.Split(*host, ",")
-	for _, h := range hosts {
-		if ip := net.ParseIP(h); ip != nil {
-			template.IPAddresses = append(template.IPAddresses, ip)
-		} else {
-			template.DNSNames = append(template.DNSNames, h)
-		}
-	}
-
-	if *isCA {
-		if *allowDC {
-			log.Fatal("Failed to create certificate: ca is not allowed with the dc flag")
-		}
-
-		template.IsCA = true
-		template.KeyUsage |= x509.KeyUsageCertSign
-	}
-
-	if *allowDC {
-		template.AllowDC = true
-		template.KeyUsage |= x509.KeyUsageDigitalSignature
-	}
-
-	derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(priv), priv)
-	if err != nil {
-		log.Fatalf("Failed to create certificate: %v", err)
-	}
-
-	certOut, err := os.Create("cert.pem")
-	if err != nil {
-		log.Fatalf("Failed to open cert.pem for writing: %v", err)
-	}
-	if err := pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}); err != nil {
-		log.Fatalf("Failed to write data to cert.pem: %v", err)
-	}
-	if err := certOut.Close(); err != nil {
-		log.Fatalf("Error closing cert.pem: %v", err)
-	}
-	log.Print("wrote cert.pem\n")
-
-	keyOut, err := os.OpenFile("key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0o600)
-	if err != nil {
-		log.Fatalf("Failed to open key.pem for writing: %v", err)
-		return
-	}
-	privBytes, err := x509.MarshalPKCS8PrivateKey(priv)
-	if err != nil {
-		log.Fatalf("Unable to marshal private key: %v", err)
-	}
-	if err := pem.Encode(keyOut, &pem.Block{Type: "PRIVATE KEY", Bytes: privBytes}); err != nil {
-		log.Fatalf("Failed to write data to key.pem: %v", err)
-	}
-	if err := keyOut.Close(); err != nil {
-		log.Fatalf("Error closing key.pem: %v", err)
-	}
-	log.Print("wrote key.pem\n")
-}

+ 0 - 126
transport/cloudflaretls/generate_delegated_credential.go

@@ -1,126 +0,0 @@
-// Copyright 2022 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.
-
-//go:build ignore
-
-// Generate a delegated credential with the given signature scheme, signed with
-// the given x.509 key pair. Outputs to 'dc.cred' and 'dckey.pem' and will
-// overwrite existing files.
-
-// Example usage:
-// generate_delegated_credential -cert-path cert.pem -key-path key.pem -signature-scheme Ed25519 -duration 24h
-
-package main
-
-import (
-	"crypto"
-	"crypto/ecdsa"
-	"crypto/ed25519"
-	"crypto/rsa"
-	"crypto/tls"
-	"crypto/x509"
-	"encoding/pem"
-	"errors"
-	"flag"
-	"fmt"
-	"log"
-	"os"
-	"path/filepath"
-	"time"
-
-	circlSign "github.com/cloudflare/circl/sign"
-)
-
-var (
-	validFor        = flag.Duration("duration", 5*24*time.Hour, "Duration that credential is valid for")
-	signatureScheme = flag.String("signature-scheme", "", "The signature scheme used by the DC")
-	certPath        = flag.String("cert-path", "./cert.pem", "Path to signing cert")
-	keyPath         = flag.String("key-path", "./key.pem", "Path to signing key")
-	isClient        = flag.Bool("client-dc", false, "Create a client Delegated Credential")
-	outPath         = flag.String("out-path", "./", "Path to output directory")
-)
-
-var SigStringMap = map[string]tls.SignatureScheme{
-	// ECDSA algorithms. Only constrained to a specific curve in TLS 1.3.
-	"ECDSAWithP256AndSHA256": tls.ECDSAWithP256AndSHA256,
-	"ECDSAWithP384AndSHA384": tls.ECDSAWithP384AndSHA384,
-	"ECDSAWithP521AndSHA512": tls.ECDSAWithP521AndSHA512,
-
-	// EdDSA algorithms.
-	"Ed25519": tls.Ed25519,
-}
-
-func main() {
-	flag.Parse()
-	sa := SigStringMap[*signatureScheme]
-
-	cert, err := tls.LoadX509KeyPair(*certPath, *keyPath)
-	if err != nil {
-		log.Fatalf("Failed to load certificate and key: %v", err)
-	}
-	cert.Leaf, err = x509.ParseCertificate(cert.Certificate[0])
-	if err != nil {
-		log.Fatalf("Failed to parse leaf certificate: %v", err)
-	}
-
-	validTime := time.Since(cert.Leaf.NotBefore) + *validFor
-	dc, priv, err := tls.NewDelegatedCredential(&cert, sa, validTime, *isClient)
-	if err != nil {
-		log.Fatalf("Failed to create a DC: %v\n", err)
-	}
-	dcBytes, err := dc.Marshal()
-	if err != nil {
-		log.Fatalf("Failed to marshal DC: %v\n", err)
-	}
-
-	DCOut, err := os.Create(filepath.Join(*outPath, "dc.cred"))
-	if err != nil {
-		log.Fatalf("Failed to open dc.cred for writing: %v", err)
-	}
-
-	DCOut.Write(dcBytes)
-	if err := DCOut.Close(); err != nil {
-		log.Fatalf("Error closing dc.cred: %v", err)
-	}
-	log.Print("wrote dc.cred\n")
-
-	derBytes, err := x509.MarshalPKCS8PrivateKey(priv)
-	if err != nil {
-		log.Fatalf("Failed to marshal DC private key: %v\n", err)
-	}
-
-	DCKeyOut, err := os.Create(filepath.Join(*outPath, "dckey.pem"))
-	if err != nil {
-		log.Fatalf("Failed to open dckey.pem for writing: %v", err)
-	}
-
-	if err := pem.Encode(DCKeyOut, &pem.Block{Type: "PRIVATE KEY", Bytes: derBytes}); err != nil {
-		log.Fatalf("Failed to write data to dckey.pem: %v\n", err)
-	}
-	if err := DCKeyOut.Close(); err != nil {
-		log.Fatalf("Error closing dckey.pem: %v\n", err)
-	}
-	log.Print("wrote dckey.pem\n")
-
-	fmt.Println("Success")
-}
-
-// Copied from tls.go, because it's private.
-func parsePrivateKey(der []byte) (crypto.PrivateKey, error) {
-	if key, err := x509.ParsePKCS1PrivateKey(der); err == nil {
-		return key, nil
-	}
-	if key, err := x509.ParsePKCS8PrivateKey(der); err == nil {
-		switch key := key.(type) {
-		case *rsa.PrivateKey, *ecdsa.PrivateKey, ed25519.PrivateKey, circlSign.PrivateKey:
-			return key, nil
-		default:
-			return nil, errors.New("tls: found unknown private key type in PKCS#8 wrapping")
-		}
-	}
-	if key, err := x509.ParseECPrivateKey(der); err == nil {
-		return key, nil
-	}
-
-	return nil, errors.New("tls: failed to parse private key")
-}

+ 0 - 1069
transport/cloudflaretls/handshake_client.go

@@ -1,1069 +0,0 @@
-// Copyright 2009 The Go Authors. 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 (
-	"bytes"
-	"context"
-	"crypto"
-	"crypto/ecdsa"
-	"crypto/ed25519"
-	"crypto/rsa"
-	"crypto/subtle"
-	"crypto/x509"
-	"errors"
-	"fmt"
-	"hash"
-	"io"
-	"net"
-	"strings"
-	"sync/atomic"
-	"time"
-
-	circlSign "github.com/cloudflare/circl/sign"
-)
-
-type clientHandshakeState struct {
-	c            *Conn
-	ctx          context.Context
-	serverHello  *serverHelloMsg
-	hello        *clientHelloMsg
-	suite        *cipherSuite
-	finishedHash finishedHash
-	masterSecret []byte
-	session      *ClientSessionState
-}
-
-func (c *Conn) makeClientHello(minVersion uint16) (*clientHelloMsg, clientKeySharePrivate, error) {
-	config := c.config
-	if len(config.ServerName) == 0 && !config.InsecureSkipVerify {
-		return nil, nil, errors.New("tls: either ServerName or InsecureSkipVerify must be specified in the tls.Config")
-	}
-
-	nextProtosLength := 0
-	for _, proto := range config.NextProtos {
-		if l := len(proto); l == 0 || l > 255 {
-			return nil, nil, errors.New("tls: invalid NextProtos value")
-		} else {
-			nextProtosLength += 1 + l
-		}
-	}
-	if nextProtosLength > 0xffff {
-		return nil, nil, errors.New("tls: NextProtos values too large")
-	}
-
-	supportedVersions := config.supportedVersionsFromMin(roleClient, minVersion)
-	if len(supportedVersions) == 0 {
-		return nil, nil, errors.New("tls: no supported versions satisfy MinVersion and MaxVersion")
-	}
-
-	clientHelloVersion := config.maxSupportedVersion(roleClient)
-	// The version at the beginning of the ClientHello was capped at TLS 1.2
-	// for compatibility reasons. The supported_versions extension is used
-	// to negotiate versions now. See RFC 8446, Section 4.2.1.
-	if clientHelloVersion > VersionTLS12 {
-		clientHelloVersion = VersionTLS12
-	}
-
-	hello := &clientHelloMsg{
-		vers:                         clientHelloVersion,
-		compressionMethods:           []uint8{compressionNone},
-		random:                       make([]byte, 32),
-		sessionId:                    make([]byte, 32),
-		ocspStapling:                 true,
-		scts:                         true,
-		serverName:                   hostnameInSNI(config.ServerName),
-		supportedCurves:              config.curvePreferences(),
-		supportedPoints:              []uint8{pointFormatUncompressed},
-		secureRenegotiationSupported: true,
-		alpnProtocols:                config.NextProtos,
-		supportedVersions:            supportedVersions,
-	}
-
-	if c.handshakes > 0 {
-		hello.secureRenegotiation = c.clientFinished[:]
-	}
-
-	preferenceOrder := cipherSuitesPreferenceOrder
-	if !hasAESGCMHardwareSupport {
-		preferenceOrder = cipherSuitesPreferenceOrderNoAES
-	}
-	configCipherSuites := config.cipherSuites()
-	hello.cipherSuites = make([]uint16, 0, len(configCipherSuites))
-
-	for _, suiteId := range preferenceOrder {
-		suite := mutualCipherSuite(configCipherSuites, suiteId)
-		if suite == nil {
-			continue
-		}
-		// Don't advertise TLS 1.2-only cipher suites unless
-		// we're attempting TLS 1.2.
-		if hello.vers < VersionTLS12 && suite.flags&suiteTLS12 != 0 {
-			continue
-		}
-		hello.cipherSuites = append(hello.cipherSuites, suiteId)
-	}
-
-	_, err := io.ReadFull(config.rand(), hello.random)
-	if err != nil {
-		return nil, nil, errors.New("tls: short read from Rand: " + err.Error())
-	}
-
-	// A random session ID is used to detect when the server accepted a ticket
-	// and is resuming a session (see RFC 5077). In TLS 1.3, it's always set as
-	// a compatibility measure (see RFC 8446, Section 4.1.2).
-	if _, err := io.ReadFull(config.rand(), hello.sessionId); err != nil {
-		return nil, nil, errors.New("tls: short read from Rand: " + err.Error())
-	}
-
-	if hello.vers >= VersionTLS12 {
-		hello.supportedSignatureAlgorithms = config.supportedSignatureAlgorithms()
-	}
-
-	var secret clientKeySharePrivate
-	if hello.supportedVersions[0] == VersionTLS13 {
-		if hasAESGCMHardwareSupport {
-			hello.cipherSuites = append(hello.cipherSuites, defaultCipherSuitesTLS13...)
-		} else {
-			hello.cipherSuites = append(hello.cipherSuites, defaultCipherSuitesTLS13NoAES...)
-		}
-
-		curveID := config.curvePreferences()[0]
-		if scheme := curveIdToCirclScheme(curveID); scheme != nil {
-			pk, sk, err := generateKemKeyPair(scheme, config.rand())
-			if err != nil {
-				return nil, nil, fmt.Errorf("generateKemKeyPair %s: %w",
-					scheme.Name(), err)
-			}
-			packedPk, err := pk.MarshalBinary()
-			if err != nil {
-				return nil, nil, fmt.Errorf("pack circl public key %s: %w",
-					scheme.Name(), err)
-			}
-			hello.keyShares = []keyShare{{group: curveID, data: packedPk}}
-			secret = sk
-		} else {
-			if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok {
-				return nil, nil, errors.New("tls: CurvePreferences includes unsupported curve")
-			}
-			params, err := generateECDHEParameters(config.rand(), curveID)
-			if err != nil {
-				return nil, nil, err
-			}
-			hello.keyShares = []keyShare{{group: curveID, data: params.PublicKey()}}
-			secret = params
-		}
-
-		hello.delegatedCredentialSupported = config.SupportDelegatedCredential
-		hello.supportedSignatureAlgorithmsDC = supportedSignatureAlgorithmsDC
-	}
-
-	return hello, secret, nil
-}
-
-func (c *Conn) clientHandshake(ctx context.Context) (err error) {
-	if c.config == nil {
-		c.config = defaultConfig()
-	}
-
-	hsTimings := createTLS13ClientHandshakeTimingInfo(c.config.Time)
-
-	// This may be a renegotiation handshake, in which case some fields
-	// need to be reset.
-	c.didResume = false
-
-	// Determine the minimum required version for this handshake.
-	minVersion := c.config.MinVersion
-	if c.config.echCanOffer() {
-		// If the ECH extension will be offered in this handshake, then the
-		// ClientHelloInner must not offer TLS 1.2 or below.
-		minVersion = VersionTLS13
-	}
-
-	helloBase, ecdheParams, err := c.makeClientHello(minVersion)
-	if err != nil {
-		return err
-	}
-
-	hello, helloInner, err := c.echOfferOrGrease(ctx, helloBase)
-	if err != nil {
-		return err
-	}
-
-	helloResumed := hello
-	if c.ech.offered {
-		helloResumed = helloInner
-	}
-
-	cacheKey, session, earlySecret, binderKey := c.loadSession(helloResumed)
-	if cacheKey != "" && session != nil {
-		defer func() {
-			// If we got a handshake failure when resuming a session, throw away
-			// the session ticket. See RFC 5077, Section 3.2.
-			//
-			// RFC 8446 makes no mention of dropping tickets on failure, but it
-			// does require servers to abort on invalid binders, so we need to
-			// delete tickets to recover from a corrupted PSK.
-			if err != nil {
-				c.config.ClientSessionCache.Put(cacheKey, nil)
-			}
-		}()
-	}
-
-	if _, err := c.writeRecord(recordTypeHandshake, hello.marshal()); err != nil {
-		return err
-	}
-
-	hsTimings.WriteClientHello = hsTimings.elapsedTime()
-
-	msg, err := c.readHandshake()
-	if err != nil {
-		return err
-	}
-
-	serverHello, ok := msg.(*serverHelloMsg)
-	if !ok {
-		c.sendAlert(alertUnexpectedMessage)
-		return unexpectedMessageError(serverHello, msg)
-	}
-
-	if err := c.pickTLSVersion(serverHello); err != nil {
-		return err
-	}
-
-	// If we are negotiating a protocol version that's lower than what we
-	// support, check for the server downgrade canaries.
-	// See RFC 8446, Section 4.1.3.
-	maxVers := c.config.maxSupportedVersion(roleClient)
-	tls12Downgrade := string(serverHello.random[24:]) == downgradeCanaryTLS12
-	tls11Downgrade := string(serverHello.random[24:]) == downgradeCanaryTLS11
-	if maxVers == VersionTLS13 && c.vers <= VersionTLS12 && (tls12Downgrade || tls11Downgrade) ||
-		maxVers == VersionTLS12 && c.vers <= VersionTLS11 && tls11Downgrade {
-		c.sendAlert(alertIllegalParameter)
-		return errors.New("tls: downgrade attempt detected, possibly due to a MitM attack or a broken middlebox")
-	}
-
-	if c.vers == VersionTLS13 {
-		hs := &clientHandshakeStateTLS13{
-			c:               c,
-			ctx:             ctx,
-			serverHello:     serverHello,
-			hello:           hello,
-			helloInner:      helloInner,
-			keySharePrivate: ecdheParams,
-			session:         session,
-			earlySecret:     earlySecret,
-			binderKey:       binderKey,
-			hsTimings:       hsTimings,
-		}
-
-		// In TLS 1.3, session tickets are delivered after the handshake.
-		return hs.handshake()
-	}
-
-	c.serverName = hello.serverName
-	hs := &clientHandshakeState{
-		c:           c,
-		ctx:         ctx,
-		serverHello: serverHello,
-		hello:       hello,
-		session:     session,
-	}
-
-	if err := hs.handshake(); err != nil {
-		return err
-	}
-
-	// If we had a successful handshake and hs.session is different from
-	// the one already cached - cache a new one.
-	if cacheKey != "" && hs.session != nil && session != hs.session {
-		c.config.ClientSessionCache.Put(cacheKey, hs.session)
-	}
-
-	return nil
-}
-
-func (c *Conn) loadSession(hello *clientHelloMsg) (cacheKey string,
-	session *ClientSessionState, earlySecret, binderKey []byte,
-) {
-	if c.config.SessionTicketsDisabled || c.config.ClientSessionCache == nil || c.config.ECHEnabled {
-		return "", nil, nil, nil
-	}
-
-	hello.ticketSupported = true
-
-	if hello.supportedVersions[0] == VersionTLS13 {
-		// Require DHE on resumption as it guarantees forward secrecy against
-		// compromise of the session ticket key. See RFC 8446, Section 4.2.9.
-		hello.pskModes = []uint8{pskModeDHE}
-	}
-
-	// Session resumption is not allowed if renegotiating because
-	// renegotiation is primarily used to allow a client to send a client
-	// certificate, which would be skipped if session resumption occurred.
-	if c.handshakes != 0 {
-		return "", nil, nil, nil
-	}
-
-	// Try to resume a previously negotiated TLS session, if available.
-	cacheKey = clientSessionCacheKey(c.conn.RemoteAddr(), c.config)
-	session, ok := c.config.ClientSessionCache.Get(cacheKey)
-	if !ok || session == nil {
-		return cacheKey, nil, nil, nil
-	}
-
-	// Check that version used for the previous session is still valid.
-	versOk := false
-	for _, v := range hello.supportedVersions {
-		if v == session.vers {
-			versOk = true
-			break
-		}
-	}
-	if !versOk {
-		return cacheKey, nil, nil, nil
-	}
-
-	// Check that the cached server certificate is not expired, and that it's
-	// valid for the ServerName. This should be ensured by the cache key, but
-	// protect the application from a faulty ClientSessionCache implementation.
-	if !c.config.InsecureSkipVerify {
-		if len(session.verifiedChains) == 0 {
-			// The original connection had InsecureSkipVerify, while this doesn't.
-			return cacheKey, nil, nil, nil
-		}
-		serverCert := session.serverCertificates[0]
-		if c.config.time().After(serverCert.NotAfter) {
-			// Expired certificate, delete the entry.
-			c.config.ClientSessionCache.Put(cacheKey, nil)
-			return cacheKey, nil, nil, nil
-		}
-		if err := serverCert.VerifyHostname(c.config.ServerName); err != nil {
-			return cacheKey, nil, nil, nil
-		}
-	}
-
-	if session.vers != VersionTLS13 {
-		// In TLS 1.2 the cipher suite must match the resumed session. Ensure we
-		// are still offering it.
-		if mutualCipherSuite(hello.cipherSuites, session.cipherSuite) == nil {
-			return cacheKey, nil, nil, nil
-		}
-
-		hello.sessionTicket = session.sessionTicket
-		return
-	}
-
-	// Check that the session ticket is not expired.
-	if c.config.time().After(session.useBy) {
-		c.config.ClientSessionCache.Put(cacheKey, nil)
-		return cacheKey, nil, nil, nil
-	}
-
-	// In TLS 1.3 the KDF hash must match the resumed session. Ensure we
-	// offer at least one cipher suite with that hash.
-	cipherSuite := cipherSuiteTLS13ByID(session.cipherSuite)
-	if cipherSuite == nil {
-		return cacheKey, nil, nil, nil
-	}
-	cipherSuiteOk := false
-	for _, offeredID := range hello.cipherSuites {
-		offeredSuite := cipherSuiteTLS13ByID(offeredID)
-		if offeredSuite != nil && offeredSuite.hash == cipherSuite.hash {
-			cipherSuiteOk = true
-			break
-		}
-	}
-	if !cipherSuiteOk {
-		return cacheKey, nil, nil, nil
-	}
-
-	// Set the pre_shared_key extension. See RFC 8446, Section 4.2.11.1.
-	ticketAge := uint32(c.config.time().Sub(session.receivedAt) / time.Millisecond)
-	identity := pskIdentity{
-		label:               session.sessionTicket,
-		obfuscatedTicketAge: ticketAge + session.ageAdd,
-	}
-	hello.pskIdentities = []pskIdentity{identity}
-	hello.pskBinders = [][]byte{make([]byte, cipherSuite.hash.Size())}
-
-	// Compute the PSK binders. See RFC 8446, Section 4.2.11.2.
-	psk := cipherSuite.expandLabel(session.masterSecret, "resumption",
-		session.nonce, cipherSuite.hash.Size())
-	earlySecret = cipherSuite.extract(psk, nil)
-	binderKey = cipherSuite.deriveSecret(earlySecret, resumptionBinderLabel, nil)
-	transcript := cipherSuite.hash.New()
-	transcript.Write(hello.marshalWithoutBinders())
-	pskBinders := [][]byte{cipherSuite.finishedHash(binderKey, transcript)}
-	hello.updateBinders(pskBinders)
-
-	return
-}
-
-func (c *Conn) pickTLSVersion(serverHello *serverHelloMsg) error {
-	peerVersion := serverHello.vers
-	if serverHello.supportedVersion != 0 {
-		peerVersion = serverHello.supportedVersion
-	}
-
-	vers, ok := c.config.mutualVersion(roleClient, []uint16{peerVersion})
-	if !ok {
-		c.sendAlert(alertProtocolVersion)
-		return fmt.Errorf("tls: server selected unsupported protocol version %x", peerVersion)
-	}
-
-	c.vers = vers
-	c.haveVers = true
-	c.in.version = vers
-	c.out.version = vers
-
-	return nil
-}
-
-// Does the handshake, either a full one or resumes old session. Requires hs.c,
-// hs.hello, hs.serverHello, and, optionally, hs.session to be set.
-func (hs *clientHandshakeState) handshake() error {
-	c := hs.c
-
-	isResume, err := hs.processServerHello()
-	if err != nil {
-		return err
-	}
-
-	hs.finishedHash = newFinishedHash(c.vers, hs.suite)
-
-	// No signatures of the handshake are needed in a resumption.
-	// Otherwise, in a full handshake, if we don't have any certificates
-	// configured then we will never send a CertificateVerify message and
-	// thus no signatures are needed in that case either.
-	if isResume || (len(c.config.Certificates) == 0 && c.config.GetClientCertificate == nil) {
-		hs.finishedHash.discardHandshakeBuffer()
-	}
-
-	hs.finishedHash.Write(hs.hello.marshal())
-	hs.finishedHash.Write(hs.serverHello.marshal())
-
-	c.buffering = true
-	c.didResume = isResume
-	if isResume {
-		if err := hs.establishKeys(); err != nil {
-			return err
-		}
-		if err := hs.readSessionTicket(); err != nil {
-			return err
-		}
-		if err := hs.readFinished(c.serverFinished[:]); err != nil {
-			return err
-		}
-		c.clientFinishedIsFirst = false
-		// Make sure the connection is still being verified whether or not this
-		// is a resumption. Resumptions currently don't reverify certificates so
-		// they don't call verifyServerCertificate. See Issue 31641.
-		if c.config.VerifyConnection != nil {
-			if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil {
-				c.sendAlert(alertBadCertificate)
-				return err
-			}
-		}
-		if err := hs.sendFinished(c.clientFinished[:]); err != nil {
-			return err
-		}
-		if _, err := c.flush(); err != nil {
-			return err
-		}
-	} else {
-		if err := hs.doFullHandshake(); err != nil {
-			return err
-		}
-		if err := hs.establishKeys(); err != nil {
-			return err
-		}
-		if err := hs.sendFinished(c.clientFinished[:]); err != nil {
-			return err
-		}
-		if _, err := c.flush(); err != nil {
-			return err
-		}
-		c.clientFinishedIsFirst = true
-		if err := hs.readSessionTicket(); err != nil {
-			return err
-		}
-		if err := hs.readFinished(c.serverFinished[:]); err != nil {
-			return err
-		}
-	}
-
-	c.ekm = ekmFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random)
-	atomic.StoreUint32(&c.handshakeStatus, 1)
-
-	return nil
-}
-
-func (hs *clientHandshakeState) pickCipherSuite() error {
-	if hs.suite = mutualCipherSuite(hs.hello.cipherSuites, hs.serverHello.cipherSuite); hs.suite == nil {
-		hs.c.sendAlert(alertHandshakeFailure)
-		return errors.New("tls: server chose an unconfigured cipher suite")
-	}
-
-	hs.c.cipherSuite = hs.suite.id
-	return nil
-}
-
-func (hs *clientHandshakeState) doFullHandshake() error {
-	c := hs.c
-
-	msg, err := c.readHandshake()
-	if err != nil {
-		return err
-	}
-	certMsg, ok := msg.(*certificateMsg)
-	if !ok || len(certMsg.certificates) == 0 {
-		c.sendAlert(alertUnexpectedMessage)
-		return unexpectedMessageError(certMsg, msg)
-	}
-	hs.finishedHash.Write(certMsg.marshal())
-
-	msg, err = c.readHandshake()
-	if err != nil {
-		return err
-	}
-
-	cs, ok := msg.(*certificateStatusMsg)
-	if ok {
-		// RFC4366 on Certificate Status Request:
-		// The server MAY return a "certificate_status" message.
-
-		if !hs.serverHello.ocspStapling {
-			// If a server returns a "CertificateStatus" message, then the
-			// server MUST have included an extension of type "status_request"
-			// with empty "extension_data" in the extended server hello.
-
-			c.sendAlert(alertUnexpectedMessage)
-			return errors.New("tls: received unexpected CertificateStatus message")
-		}
-		hs.finishedHash.Write(cs.marshal())
-
-		c.ocspResponse = cs.response
-
-		msg, err = c.readHandshake()
-		if err != nil {
-			return err
-		}
-	}
-
-	if c.handshakes == 0 {
-		// If this is the first handshake on a connection, process and
-		// (optionally) verify the server's certificates.
-		if err := c.verifyServerCertificate(certMsg.certificates); err != nil {
-			return err
-		}
-	} else {
-		// This is a renegotiation handshake. We require that the
-		// server's identity (i.e. leaf certificate) is unchanged and
-		// thus any previous trust decision is still valid.
-		//
-		// See https://mitls.org/pages/attacks/3SHAKE for the
-		// motivation behind this requirement.
-		if !bytes.Equal(c.peerCertificates[0].Raw, certMsg.certificates[0]) {
-			c.sendAlert(alertBadCertificate)
-			return errors.New("tls: server's identity changed during renegotiation")
-		}
-	}
-
-	keyAgreement := hs.suite.ka(c.vers)
-
-	skx, ok := msg.(*serverKeyExchangeMsg)
-	if ok {
-		hs.finishedHash.Write(skx.marshal())
-		err = keyAgreement.processServerKeyExchange(c.config, hs.hello, hs.serverHello, c.peerCertificates[0], skx)
-		if err != nil {
-			c.sendAlert(alertUnexpectedMessage)
-			return err
-		}
-
-		if eccKex, ok := keyAgreement.(*ecdheKeyAgreement); ok {
-			c.handleCFEvent(CFEventTLSNegotiatedNamedKEX{
-				KEX: eccKex.params.CurveID(),
-			})
-		}
-
-		msg, err = c.readHandshake()
-		if err != nil {
-			return err
-		}
-	}
-
-	var chainToSend *Certificate
-	var certRequested bool
-	certReq, ok := msg.(*certificateRequestMsg)
-	if ok {
-		certRequested = true
-		hs.finishedHash.Write(certReq.marshal())
-
-		cri := certificateRequestInfoFromMsg(hs.ctx, c.vers, certReq)
-		if chainToSend, err = c.getClientCertificate(cri); err != nil {
-			c.sendAlert(alertInternalError)
-			return err
-		}
-
-		msg, err = c.readHandshake()
-		if err != nil {
-			return err
-		}
-	}
-
-	shd, ok := msg.(*serverHelloDoneMsg)
-	if !ok {
-		c.sendAlert(alertUnexpectedMessage)
-		return unexpectedMessageError(shd, msg)
-	}
-	hs.finishedHash.Write(shd.marshal())
-
-	// If the server requested a certificate then we have to send a
-	// Certificate message, even if it's empty because we don't have a
-	// certificate to send.
-	if certRequested {
-		certMsg = new(certificateMsg)
-		certMsg.certificates = chainToSend.Certificate
-		hs.finishedHash.Write(certMsg.marshal())
-		if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil {
-			return err
-		}
-	}
-
-	preMasterSecret, ckx, err := keyAgreement.generateClientKeyExchange(c.config, hs.hello, c.peerCertificates[0])
-	if err != nil {
-		c.sendAlert(alertInternalError)
-		return err
-	}
-	if ckx != nil {
-		hs.finishedHash.Write(ckx.marshal())
-		if _, err := c.writeRecord(recordTypeHandshake, ckx.marshal()); err != nil {
-			return err
-		}
-	}
-
-	if chainToSend != nil && len(chainToSend.Certificate) > 0 {
-		certVerify := &certificateVerifyMsg{}
-
-		key, ok := chainToSend.PrivateKey.(crypto.Signer)
-		if !ok {
-			c.sendAlert(alertInternalError)
-			return fmt.Errorf("tls: client certificate private key of type %T does not implement crypto.Signer", chainToSend.PrivateKey)
-		}
-
-		var sigType uint8
-		var sigHash crypto.Hash
-		if c.vers >= VersionTLS12 {
-			signatureAlgorithm, err := selectSignatureScheme(c.vers, chainToSend, certReq.supportedSignatureAlgorithms)
-			if err != nil {
-				c.sendAlert(alertIllegalParameter)
-				return err
-			}
-			sigType, sigHash, err = typeAndHashFromSignatureScheme(signatureAlgorithm)
-			if err != nil {
-				return c.sendAlert(alertInternalError)
-			}
-			certVerify.hasSignatureAlgorithm = true
-			certVerify.signatureAlgorithm = signatureAlgorithm
-		} else {
-			sigType, sigHash, err = legacyTypeAndHashFromPublicKey(key.Public())
-			if err != nil {
-				c.sendAlert(alertIllegalParameter)
-				return err
-			}
-		}
-
-		signed := hs.finishedHash.hashForClientCertificate(sigType, sigHash, hs.masterSecret)
-		signOpts := crypto.SignerOpts(sigHash)
-		if sigType == signatureRSAPSS {
-			signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash}
-		}
-		certVerify.signature, err = key.Sign(c.config.rand(), signed, signOpts)
-		if err != nil {
-			c.sendAlert(alertInternalError)
-			return err
-		}
-
-		hs.finishedHash.Write(certVerify.marshal())
-		if _, err := c.writeRecord(recordTypeHandshake, certVerify.marshal()); err != nil {
-			return err
-		}
-	}
-
-	hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.hello.random, hs.serverHello.random)
-	if err := c.config.writeKeyLog(keyLogLabelTLS12, hs.hello.random, hs.masterSecret); err != nil {
-		c.sendAlert(alertInternalError)
-		return errors.New("tls: failed to write to key log: " + err.Error())
-	}
-
-	hs.finishedHash.discardHandshakeBuffer()
-
-	return nil
-}
-
-func (hs *clientHandshakeState) establishKeys() error {
-	c := hs.c
-
-	clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV := keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen)
-	var clientCipher, serverCipher any
-	var clientHash, serverHash hash.Hash
-	if hs.suite.cipher != nil {
-		clientCipher = hs.suite.cipher(clientKey, clientIV, false /* not for reading */)
-		clientHash = hs.suite.mac(clientMAC)
-		serverCipher = hs.suite.cipher(serverKey, serverIV, true /* for reading */)
-		serverHash = hs.suite.mac(serverMAC)
-	} else {
-		clientCipher = hs.suite.aead(clientKey, clientIV)
-		serverCipher = hs.suite.aead(serverKey, serverIV)
-	}
-
-	c.in.prepareCipherSpec(c.vers, serverCipher, serverHash)
-	c.out.prepareCipherSpec(c.vers, clientCipher, clientHash)
-	return nil
-}
-
-func (hs *clientHandshakeState) serverResumedSession() bool {
-	// If the server responded with the same sessionId then it means the
-	// sessionTicket is being used to resume a TLS session.
-	return hs.session != nil && hs.hello.sessionId != nil &&
-		bytes.Equal(hs.serverHello.sessionId, hs.hello.sessionId)
-}
-
-func (hs *clientHandshakeState) processServerHello() (bool, error) {
-	c := hs.c
-
-	if err := hs.pickCipherSuite(); err != nil {
-		return false, err
-	}
-
-	if hs.serverHello.compressionMethod != compressionNone {
-		c.sendAlert(alertUnexpectedMessage)
-		return false, errors.New("tls: server selected unsupported compression format")
-	}
-
-	if c.handshakes == 0 && hs.serverHello.secureRenegotiationSupported {
-		c.secureRenegotiation = true
-		if len(hs.serverHello.secureRenegotiation) != 0 {
-			c.sendAlert(alertHandshakeFailure)
-			return false, errors.New("tls: initial handshake had non-empty renegotiation extension")
-		}
-	}
-
-	if c.handshakes > 0 && c.secureRenegotiation {
-		var expectedSecureRenegotiation [24]byte
-		copy(expectedSecureRenegotiation[:], c.clientFinished[:])
-		copy(expectedSecureRenegotiation[12:], c.serverFinished[:])
-		if !bytes.Equal(hs.serverHello.secureRenegotiation, expectedSecureRenegotiation[:]) {
-			c.sendAlert(alertHandshakeFailure)
-			return false, errors.New("tls: incorrect renegotiation extension contents")
-		}
-	}
-
-	if err := checkALPN(hs.hello.alpnProtocols, hs.serverHello.alpnProtocol); err != nil {
-		c.sendAlert(alertUnsupportedExtension)
-		return false, err
-	}
-	c.clientProtocol = hs.serverHello.alpnProtocol
-
-	c.scts = hs.serverHello.scts
-
-	if !hs.serverResumedSession() {
-		return false, nil
-	}
-
-	if hs.session.vers != c.vers {
-		c.sendAlert(alertHandshakeFailure)
-		return false, errors.New("tls: server resumed a session with a different version")
-	}
-
-	if hs.session.cipherSuite != hs.suite.id {
-		c.sendAlert(alertHandshakeFailure)
-		return false, errors.New("tls: server resumed a session with a different cipher suite")
-	}
-
-	// Restore masterSecret, peerCerts, and ocspResponse from previous state
-	hs.masterSecret = hs.session.masterSecret
-	c.peerCertificates = hs.session.serverCertificates
-	c.verifiedChains = hs.session.verifiedChains
-	c.ocspResponse = hs.session.ocspResponse
-	// Let the ServerHello SCTs override the session SCTs from the original
-	// connection, if any are provided
-	if len(c.scts) == 0 && len(hs.session.scts) != 0 {
-		c.scts = hs.session.scts
-	}
-
-	return true, nil
-}
-
-// checkALPN ensure that the server's choice of ALPN protocol is compatible with
-// the protocols that we advertised in the Client Hello.
-func checkALPN(clientProtos []string, serverProto string) error {
-	if serverProto == "" {
-		return nil
-	}
-	if len(clientProtos) == 0 {
-		return errors.New("tls: server advertised unrequested ALPN extension")
-	}
-	for _, proto := range clientProtos {
-		if proto == serverProto {
-			return nil
-		}
-	}
-	return errors.New("tls: server selected unadvertised ALPN protocol")
-}
-
-func (hs *clientHandshakeState) readFinished(out []byte) error {
-	c := hs.c
-
-	if err := c.readChangeCipherSpec(); err != nil {
-		return err
-	}
-
-	msg, err := c.readHandshake()
-	if err != nil {
-		return err
-	}
-	serverFinished, ok := msg.(*finishedMsg)
-	if !ok {
-		c.sendAlert(alertUnexpectedMessage)
-		return unexpectedMessageError(serverFinished, msg)
-	}
-
-	verify := hs.finishedHash.serverSum(hs.masterSecret)
-	if len(verify) != len(serverFinished.verifyData) ||
-		subtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 {
-		c.sendAlert(alertHandshakeFailure)
-		return errors.New("tls: server's Finished message was incorrect")
-	}
-	hs.finishedHash.Write(serverFinished.marshal())
-	copy(out, verify)
-	return nil
-}
-
-func (hs *clientHandshakeState) readSessionTicket() error {
-	if !hs.serverHello.ticketSupported {
-		return nil
-	}
-
-	c := hs.c
-	msg, err := c.readHandshake()
-	if err != nil {
-		return err
-	}
-	sessionTicketMsg, ok := msg.(*newSessionTicketMsg)
-	if !ok {
-		c.sendAlert(alertUnexpectedMessage)
-		return unexpectedMessageError(sessionTicketMsg, msg)
-	}
-	hs.finishedHash.Write(sessionTicketMsg.marshal())
-
-	hs.session = &ClientSessionState{
-		sessionTicket:      sessionTicketMsg.ticket,
-		vers:               c.vers,
-		cipherSuite:        hs.suite.id,
-		masterSecret:       hs.masterSecret,
-		serverCertificates: c.peerCertificates,
-		verifiedChains:     c.verifiedChains,
-		receivedAt:         c.config.time(),
-		ocspResponse:       c.ocspResponse,
-		scts:               c.scts,
-	}
-
-	return nil
-}
-
-func (hs *clientHandshakeState) sendFinished(out []byte) error {
-	c := hs.c
-
-	if _, err := c.writeRecord(recordTypeChangeCipherSpec, []byte{1}); err != nil {
-		return err
-	}
-
-	finished := new(finishedMsg)
-	finished.verifyData = hs.finishedHash.clientSum(hs.masterSecret)
-	hs.finishedHash.Write(finished.marshal())
-	if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil {
-		return err
-	}
-	copy(out, finished.verifyData)
-	return nil
-}
-
-// verifyServerCertificate parses and verifies the provided chain, setting
-// c.verifiedChains and c.peerCertificates or sending the appropriate alert.
-func (c *Conn) verifyServerCertificate(certificates [][]byte) error {
-	certs := make([]*x509.Certificate, len(certificates))
-	for i, asn1Data := range certificates {
-		cert, err := x509.ParseCertificate(asn1Data)
-		if err != nil {
-			c.sendAlert(alertBadCertificate)
-			return errors.New("tls: failed to parse certificate from server: " + err.Error())
-		}
-		certs[i] = cert
-	}
-
-	if !c.config.InsecureSkipVerify {
-		dnsName := c.config.ServerName
-		if c.ech.offered && !c.ech.accepted {
-			dnsName = c.serverName
-		}
-		opts := x509.VerifyOptions{
-			Roots:         c.config.RootCAs,
-			CurrentTime:   c.config.time(),
-			DNSName:       dnsName,
-			Intermediates: x509.NewCertPool(),
-		}
-		for _, cert := range certs[1:] {
-			opts.Intermediates.AddCert(cert)
-		}
-		var err error
-		c.verifiedChains, err = certs[0].Verify(opts)
-		if err != nil {
-			c.sendAlert(alertBadCertificate)
-			return err
-		}
-	}
-
-	switch certs[0].PublicKey.(type) {
-	case *rsa.PublicKey, *ecdsa.PublicKey, ed25519.PublicKey, circlSign.PublicKey:
-		break
-	default:
-		c.sendAlert(alertUnsupportedCertificate)
-		return fmt.Errorf("tls: server's certificate contains an unsupported type of public key: %T", certs[0].PublicKey)
-	}
-
-	c.peerCertificates = certs
-
-	if c.config.VerifyPeerCertificate != nil {
-		if err := c.config.VerifyPeerCertificate(certificates, c.verifiedChains); err != nil {
-			c.sendAlert(alertBadCertificate)
-			return err
-		}
-	}
-
-	if c.config.VerifyConnection != nil {
-		if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil {
-			c.sendAlert(alertBadCertificate)
-			return err
-		}
-	}
-
-	return nil
-}
-
-// certificateRequestInfoFromMsg generates a CertificateRequestInfo from a TLS
-// <= 1.2 CertificateRequest, making an effort to fill in missing information.
-func certificateRequestInfoFromMsg(ctx context.Context, vers uint16, certReq *certificateRequestMsg) *CertificateRequestInfo {
-	cri := &CertificateRequestInfo{
-		AcceptableCAs: certReq.certificateAuthorities,
-		Version:       vers,
-		ctx:           ctx,
-
-		SupportsDelegatedCredential: false, // Not supported in TLS <= 1.2
-		SignatureSchemesDC:          nil,   // Not supported in TLS <= 1.2
-	}
-
-	var rsaAvail, ecAvail bool
-	for _, certType := range certReq.certificateTypes {
-		switch certType {
-		case certTypeRSASign:
-			rsaAvail = true
-		case certTypeECDSASign:
-			ecAvail = true
-		}
-	}
-
-	if !certReq.hasSignatureAlgorithm {
-		// Prior to TLS 1.2, signature schemes did not exist. In this case we
-		// make up a list based on the acceptable certificate types, to help
-		// GetClientCertificate and SupportsCertificate select the right certificate.
-		// The hash part of the SignatureScheme is a lie here, because
-		// TLS 1.0 and 1.1 always use MD5+SHA1 for RSA and SHA1 for ECDSA.
-		switch {
-		case rsaAvail && ecAvail:
-			cri.SignatureSchemes = []SignatureScheme{
-				ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512,
-				PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512, PKCS1WithSHA1,
-			}
-		case rsaAvail:
-			cri.SignatureSchemes = []SignatureScheme{
-				PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512, PKCS1WithSHA1,
-			}
-		case ecAvail:
-			cri.SignatureSchemes = []SignatureScheme{
-				ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512,
-			}
-		}
-		return cri
-	}
-
-	// Filter the signature schemes based on the certificate types.
-	// See RFC 5246, Section 7.4.4 (where it calls this "somewhat complicated").
-	cri.SignatureSchemes = make([]SignatureScheme, 0, len(certReq.supportedSignatureAlgorithms))
-	for _, sigScheme := range certReq.supportedSignatureAlgorithms {
-		sigType, _, err := typeAndHashFromSignatureScheme(sigScheme)
-		if err != nil {
-			continue
-		}
-		switch sigType {
-		case signatureECDSA, signatureEd25519:
-			if ecAvail {
-				cri.SignatureSchemes = append(cri.SignatureSchemes, sigScheme)
-			}
-		case signatureRSAPSS, signaturePKCS1v15:
-			if rsaAvail {
-				cri.SignatureSchemes = append(cri.SignatureSchemes, sigScheme)
-			}
-		}
-	}
-
-	return cri
-}
-
-func (c *Conn) getClientCertificate(cri *CertificateRequestInfo) (*Certificate, error) {
-	if c.config.GetClientCertificate != nil {
-		return c.config.GetClientCertificate(cri)
-	}
-
-	for _, chain := range c.config.Certificates {
-		if err := cri.SupportsCertificate(&chain); err != nil {
-			continue
-		}
-		return &chain, nil
-	}
-
-	// No acceptable certificate found. Don't send a certificate.
-	return new(Certificate), nil
-}
-
-// clientSessionCacheKey returns a key used to cache sessionTickets that could
-// be used to resume previously negotiated TLS sessions with a server.
-func clientSessionCacheKey(serverAddr net.Addr, config *Config) string {
-	if len(config.ServerName) > 0 {
-		return config.ServerName
-	}
-	return serverAddr.String()
-}
-
-// hostnameInSNI converts name into an appropriate hostname for SNI.
-// Literal IP addresses and absolute FQDNs are not permitted as SNI values.
-// See RFC 6066, Section 3.
-func hostnameInSNI(name string) string {
-	host := name
-	if len(host) > 0 && host[0] == '[' && host[len(host)-1] == ']' {
-		host = host[1 : len(host)-1]
-	}
-	if i := strings.LastIndex(host, "%"); i > 0 {
-		host = host[:i]
-	}
-	if net.ParseIP(host) != nil {
-		return ""
-	}
-	for len(name) > 0 && name[len(name)-1] == '.' {
-		name = name[:len(name)-1]
-	}
-	return name
-}

+ 0 - 1032
transport/cloudflaretls/handshake_client_tls13.go

@@ -1,1032 +0,0 @@
-// Copyright 2018 The Go Authors. 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 (
-	"bytes"
-	"context"
-	"crypto"
-	"crypto/hmac"
-	"crypto/rsa"
-	"crypto/subtle"
-	"errors"
-	"fmt"
-	"hash"
-	"sync/atomic"
-	"time"
-
-	circlKem "github.com/cloudflare/circl/kem"
-)
-
-type clientHandshakeStateTLS13 struct {
-	c               *Conn
-	ctx             context.Context
-	serverHello     *serverHelloMsg
-	hello           *clientHelloMsg
-	helloInner      *clientHelloMsg
-	keySharePrivate clientKeySharePrivate
-
-	session       *ClientSessionState
-	earlySecret   []byte
-	binderKey     []byte
-	selectedGroup CurveID
-
-	certReq         *certificateRequestMsgTLS13
-	usingPSK        bool
-	sentDummyCCS    bool
-	suite           *cipherSuiteTLS13
-	transcript      hash.Hash
-	transcriptInner hash.Hash
-	masterSecret    []byte
-	trafficSecret   []byte // client_application_traffic_secret_0
-
-	hsTimings CFEventTLS13ClientHandshakeTimingInfo
-}
-
-// processDelegatedCredentialFromServer unmarshals the DelegatedCredential
-// offered by the server (if present) and validates it using the peer's
-// certificate.
-func (hs *clientHandshakeStateTLS13) processDelegatedCredentialFromServer(rawDC []byte, certVerifyMsg *certificateVerifyMsg) error {
-	c := hs.c
-
-	var dc *DelegatedCredential
-	var err error
-	if rawDC != nil {
-		// Assert that support for the DC extension was indicated by the client.
-		if !hs.hello.delegatedCredentialSupported {
-			c.sendAlert(alertUnexpectedMessage)
-			return errors.New("tls: got Delegated Credential extension without indication")
-		}
-
-		dc, err = UnmarshalDelegatedCredential(rawDC)
-		if err != nil {
-			c.sendAlert(alertDecodeError)
-			return fmt.Errorf("tls: Delegated Credential: %s", err)
-		}
-
-		if !isSupportedSignatureAlgorithm(dc.cred.expCertVerfAlgo, supportedSignatureAlgorithmsDC) {
-			c.sendAlert(alertIllegalParameter)
-			return errors.New("tls: Delegated Credential used with invalid signature algorithm")
-		}
-		if !isSupportedSignatureAlgorithm(dc.algorithm, c.config.supportedSignatureAlgorithms()) {
-			c.sendAlert(alertIllegalParameter)
-			return errors.New("tls: Delegated Credential signed with unsupported signature algorithm")
-		}
-	}
-
-	if dc != nil {
-		if !dc.Validate(c.peerCertificates[0], false, c.config.time(), certVerifyMsg) {
-			c.sendAlert(alertIllegalParameter)
-			return errors.New("tls: invalid Delegated Credential")
-		}
-	}
-
-	c.verifiedDC = dc
-
-	return nil
-}
-
-// handshake requires hs.c, hs.hello, hs.serverHello, hs.ecdheParams, and,
-// optionally, hs.session, hs.earlySecret and hs.binderKey to be set.
-func (hs *clientHandshakeStateTLS13) handshake() error {
-	c := hs.c
-
-	// The server must not select TLS 1.3 in a renegotiation. See RFC 8446,
-	// sections 4.1.2 and 4.1.3.
-	if c.handshakes > 0 {
-		c.sendAlert(alertProtocolVersion)
-		return errors.New("tls: server selected TLS 1.3 in a renegotiation")
-	}
-
-	// Consistency check on the presence of a keyShare and its parameters.
-	if hs.keySharePrivate == nil || len(hs.hello.keyShares) != 1 {
-		return c.sendAlert(alertInternalError)
-	}
-
-	if err := hs.checkServerHelloOrHRR(); err != nil {
-		return err
-	}
-
-	hs.transcript = hs.suite.hash.New()
-	hs.transcript.Write(hs.hello.marshal())
-
-	// When offering ECH, we don't know whether ECH was accepted or rejected
-	// until we get the server's response. Compute the transcript of both the
-	// inner and outer handshake until we know.
-	if c.ech.offered {
-		hs.transcriptInner = hs.suite.hash.New()
-		hs.transcriptInner.Write(hs.helloInner.marshal())
-	}
-
-	if bytes.Equal(hs.serverHello.random, helloRetryRequestRandom) {
-		if err := hs.sendDummyChangeCipherSpec(); err != nil {
-			return err
-		}
-		if err := hs.processHelloRetryRequest(); err != nil {
-			return err
-		}
-	}
-
-	// Check for ECH acceptance confirmation.
-	if c.ech.offered {
-		echAcceptConfTranscript := cloneHash(hs.transcriptInner, hs.suite.hash)
-		if echAcceptConfTranscript == nil {
-			c.sendAlert(alertInternalError)
-			return errors.New("tls: internal error: failed to clone hash")
-		}
-
-		sh := hs.serverHello.marshal()
-		echAcceptConfTranscript.Write(sh[:30])
-		echAcceptConfTranscript.Write(zeros[:8])
-		echAcceptConfTranscript.Write(sh[38:])
-		echAcceptConf := hs.suite.expandLabel(
-			hs.suite.extract(hs.helloInner.random, nil),
-			echAcceptConfLabel,
-			echAcceptConfTranscript.Sum(nil),
-			8)
-
-		if subtle.ConstantTimeCompare(hs.serverHello.random[24:], echAcceptConf) == 1 {
-			c.ech.accepted = true
-			hs.hello = hs.helloInner
-			hs.transcript = hs.transcriptInner
-		}
-	}
-
-	hs.transcript.Write(hs.serverHello.marshal())
-
-	// Resolve the server name now that ECH acceptance has been determined.
-	//
-	// NOTE(cjpatton): Currently the client sends the same ALPN extension in the
-	// ClientHelloInner and ClientHelloOuter. If that changes, then we'll need
-	// to resolve ALPN here as well.
-	c.serverName = hs.hello.serverName
-
-	c.buffering = true
-	if err := hs.processServerHello(); err != nil {
-		return err
-	}
-	if err := hs.sendDummyChangeCipherSpec(); err != nil {
-		return err
-	}
-	if err := hs.establishHandshakeKeys(); err != nil {
-		return err
-	}
-	if err := hs.readServerParameters(); err != nil {
-		return err
-	}
-	if err := hs.readServerCertificate(); err != nil {
-		return err
-	}
-	if err := hs.readServerFinished(); err != nil {
-		return err
-	}
-	if err := hs.sendClientCertificate(); err != nil {
-		return err
-	}
-	if err := hs.sendClientFinished(); err != nil {
-		return err
-	}
-	if err := hs.abortIfRequired(); err != nil {
-		return err
-	}
-	if _, err := c.flush(); err != nil {
-		return err
-	}
-
-	c.handleCFEvent(hs.hsTimings)
-	atomic.StoreUint32(&c.handshakeStatus, 1)
-
-	return nil
-}
-
-// checkServerHelloOrHRR does validity checks that apply to both ServerHello and
-// HelloRetryRequest messages. It sets hs.suite.
-func (hs *clientHandshakeStateTLS13) checkServerHelloOrHRR() error {
-	c := hs.c
-
-	if hs.serverHello.supportedVersion == 0 {
-		c.sendAlert(alertMissingExtension)
-		return errors.New("tls: server selected TLS 1.3 using the legacy version field")
-	}
-
-	if hs.serverHello.supportedVersion != VersionTLS13 {
-		c.sendAlert(alertIllegalParameter)
-		return errors.New("tls: server selected an invalid version after a HelloRetryRequest")
-	}
-
-	if hs.serverHello.vers != VersionTLS12 {
-		c.sendAlert(alertIllegalParameter)
-		return errors.New("tls: server sent an incorrect legacy version")
-	}
-
-	if hs.serverHello.ocspStapling ||
-		hs.serverHello.ticketSupported ||
-		hs.serverHello.secureRenegotiationSupported ||
-		len(hs.serverHello.secureRenegotiation) != 0 ||
-		len(hs.serverHello.alpnProtocol) != 0 ||
-		len(hs.serverHello.scts) != 0 {
-		c.sendAlert(alertUnsupportedExtension)
-		return errors.New("tls: server sent a ServerHello extension forbidden in TLS 1.3")
-	}
-
-	if !bytes.Equal(hs.hello.sessionId, hs.serverHello.sessionId) {
-		c.sendAlert(alertIllegalParameter)
-		return errors.New("tls: server did not echo the legacy session ID")
-	}
-
-	if hs.serverHello.compressionMethod != compressionNone {
-		c.sendAlert(alertIllegalParameter)
-		return errors.New("tls: server selected unsupported compression format")
-	}
-
-	selectedSuite := mutualCipherSuiteTLS13(hs.hello.cipherSuites, hs.serverHello.cipherSuite)
-	if hs.suite != nil && selectedSuite != hs.suite {
-		c.sendAlert(alertIllegalParameter)
-		return errors.New("tls: server changed cipher suite after a HelloRetryRequest")
-	}
-	if selectedSuite == nil {
-		c.sendAlert(alertIllegalParameter)
-		return errors.New("tls: server chose an unconfigured cipher suite")
-	}
-	hs.suite = selectedSuite
-	c.cipherSuite = hs.suite.id
-
-	return nil
-}
-
-// sendDummyChangeCipherSpec sends a ChangeCipherSpec record for compatibility
-// with middleboxes that didn't implement TLS correctly. See RFC 8446, Appendix D.4.
-func (hs *clientHandshakeStateTLS13) sendDummyChangeCipherSpec() error {
-	if hs.sentDummyCCS {
-		return nil
-	}
-	hs.sentDummyCCS = true
-
-	_, err := hs.c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
-	return err
-}
-
-// processHelloRetryRequest handles the HRR in hs.serverHello, modifies and
-// resends hs.hello, and reads the new ServerHello into hs.serverHello.
-func (hs *clientHandshakeStateTLS13) processHelloRetryRequest() error {
-	c := hs.c
-
-	c.handleCFEvent(CFEventTLS13HRR{})
-
-	// The first ClientHello gets double-hashed into the transcript upon a
-	// HelloRetryRequest. (The idea is that the server might offload transcript
-	// storage to the client in the cookie.) See RFC 8446, Section 4.4.1.
-	chHash := hs.transcript.Sum(nil)
-	hs.transcript.Reset()
-	hs.transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))})
-	hs.transcript.Write(chHash)
-	hs.transcript.Write(hs.serverHello.marshal())
-
-	// Determine which ClientHello message was consumed by the server. If ECH
-	// was offered, this may be the ClientHelloInner or ClientHelloOuter.
-	hello := hs.hello
-	isInner := false
-	if c.ech.offered {
-		chHash = hs.transcriptInner.Sum(nil)
-		hs.transcriptInner.Reset()
-		hs.transcriptInner.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))})
-		hs.transcriptInner.Write(chHash)
-
-		// Check for ECH acceptance confirmation.
-		if hs.serverHello.ech != nil {
-			if len(hs.serverHello.ech) != 8 {
-				c.sendAlert(alertDecodeError)
-				return errors.New("tls: ech: hrr: malformed acceptance signal")
-			}
-
-			echAcceptConfHRRTranscript := cloneHash(hs.transcriptInner, hs.suite.hash)
-			if echAcceptConfHRRTranscript == nil {
-				c.sendAlert(alertInternalError)
-				return errors.New("tls: internal error: failed to clone hash")
-			}
-
-			echAcceptConfHRR := echEncodeAcceptConfHelloRetryRequest(hs.serverHello.marshal())
-			echAcceptConfHRRTranscript.Write(echAcceptConfHRR)
-			echAcceptConfHRRSignal := hs.suite.expandLabel(
-				hs.suite.extract(hs.helloInner.random, nil),
-				echAcceptConfHRRLabel,
-				echAcceptConfHRRTranscript.Sum(nil),
-				8)
-
-			if subtle.ConstantTimeCompare(hs.serverHello.ech, echAcceptConfHRRSignal) == 1 {
-				hello = hs.helloInner
-				isInner = true
-			}
-		}
-
-		hs.transcriptInner.Write(hs.serverHello.marshal())
-	}
-
-	// The only HelloRetryRequest extensions we support are key_share and
-	// cookie, and clients must abort the handshake if the HRR would not result
-	// in any change in the ClientHello.
-	if hs.serverHello.selectedGroup == 0 && hs.serverHello.cookie == nil {
-		c.sendAlert(alertIllegalParameter)
-		return errors.New("tls: server sent an unnecessary HelloRetryRequest message")
-	}
-
-	if hs.serverHello.cookie != nil {
-		hello.cookie = hs.serverHello.cookie
-	}
-
-	if hs.serverHello.serverShare.group != 0 {
-		c.sendAlert(alertDecodeError)
-		return errors.New("tls: received malformed key_share extension")
-	}
-
-	// If the server sent a key_share extension selecting a group, ensure it's
-	// a group we advertised but did not send a key share for, and send a key
-	// share for it this time.
-	if curveID := hs.serverHello.selectedGroup; curveID != 0 {
-		curveOK := false
-		for _, id := range hello.supportedCurves {
-			if id == curveID {
-				curveOK = true
-				break
-			}
-		}
-		if !curveOK {
-			c.sendAlert(alertIllegalParameter)
-			return errors.New("tls: server selected unsupported group")
-		}
-		if clientKeySharePrivateCurveID(hs.keySharePrivate) == curveID {
-			c.sendAlert(alertIllegalParameter)
-			return errors.New("tls: server sent an unnecessary HelloRetryRequest key_share")
-		}
-		if scheme := curveIdToCirclScheme(curveID); scheme != nil {
-			pk, sk, err := generateKemKeyPair(scheme, c.config.rand())
-			if err != nil {
-				c.sendAlert(alertInternalError)
-				return fmt.Errorf("HRR generateKemKeyPair %s: %w",
-					scheme.Name(), err)
-			}
-			packedPk, err := pk.MarshalBinary()
-			if err != nil {
-				c.sendAlert(alertInternalError)
-				return fmt.Errorf("HRR pack circl public key %s: %w",
-					scheme.Name(), err)
-			}
-			hs.keySharePrivate = sk
-			hello.keyShares = []keyShare{{group: curveID, data: packedPk}}
-		} else {
-			if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok {
-				c.sendAlert(alertInternalError)
-				return errors.New("tls: CurvePreferences includes unsupported curve")
-			}
-			params, err := generateECDHEParameters(c.config.rand(), curveID)
-			if err != nil {
-				c.sendAlert(alertInternalError)
-				return err
-			}
-			hs.keySharePrivate = params
-			hello.keyShares = []keyShare{{group: curveID, data: params.PublicKey()}}
-		}
-	}
-
-	hello.raw = nil
-	if len(hello.pskIdentities) > 0 {
-		pskSuite := cipherSuiteTLS13ByID(hs.session.cipherSuite)
-		if pskSuite == nil {
-			return c.sendAlert(alertInternalError)
-		}
-		if pskSuite.hash == hs.suite.hash {
-			// Update binders and obfuscated_ticket_age.
-			ticketAge := uint32(c.config.time().Sub(hs.session.receivedAt) / time.Millisecond)
-			hello.pskIdentities[0].obfuscatedTicketAge = ticketAge + hs.session.ageAdd
-
-			transcript := hs.suite.hash.New()
-			transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))})
-			transcript.Write(chHash)
-			transcript.Write(hs.serverHello.marshal())
-			transcript.Write(hello.marshalWithoutBinders())
-			pskBinders := [][]byte{hs.suite.finishedHash(hs.binderKey, transcript)}
-			hello.updateBinders(pskBinders)
-		} else {
-			// Server selected a cipher suite incompatible with the PSK.
-			hello.pskIdentities = nil
-			hello.pskBinders = nil
-		}
-	}
-
-	if isInner {
-		hs.helloInner = hello
-		hs.transcriptInner.Write(hs.helloInner.marshal())
-		if err := c.echUpdateClientHelloOuter(hs.hello, hs.helloInner, nil); err != nil {
-			return err
-		}
-	} else {
-		hs.hello = hello
-	}
-
-	if c.ech.offered && testingECHIllegalHandleAfterHRR {
-		hs.hello.raw = nil
-
-		// Change the cipher suite and config id and set an encapsulated key in
-		// the updated ClientHello. This will trigger a server abort because the
-		// cipher suite and config id are supposed to match the previous
-		// ClientHello and the encapsulated key is supposed to be empty.
-		var ech echClientOuter
-		_, kdf, aead := c.ech.sealer.Suite().Params()
-		ech.handle.suite.kdfId = uint16(kdf) ^ 0xff
-		ech.handle.suite.aeadId = uint16(aead) ^ 0xff
-		ech.handle.configId = c.ech.configId ^ 0xff
-		ech.handle.enc = []byte{1, 2, 3, 4, 5}
-		ech.payload = []byte{1, 2, 3, 4, 5}
-		hs.hello.ech = ech.marshal()
-	}
-
-	if testingECHTriggerBypassAfterHRR {
-		hs.hello.raw = nil
-
-		// Don't send the ECH extension in the updated ClientHello. This will
-		// trigger a server abort, since this is illegal.
-		hs.hello.ech = nil
-	}
-
-	if testingECHTriggerBypassBeforeHRR {
-		hs.hello.raw = nil
-
-		// Send a dummy ECH extension in the updated ClientHello. This will
-		// trigger a server abort, since no ECH extension was sent in the
-		// previous ClientHello.
-		var err error
-		hs.hello.ech, err = echGenerateGreaseExt(c.config.rand())
-		if err != nil {
-			return fmt.Errorf("tls: ech: failed to generate grease ECH: %s", err)
-		}
-	}
-
-	if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil {
-		return err
-	}
-
-	msg, err := c.readHandshake()
-	if err != nil {
-		return err
-	}
-
-	serverHello, ok := msg.(*serverHelloMsg)
-	if !ok {
-		c.sendAlert(alertUnexpectedMessage)
-		return unexpectedMessageError(serverHello, msg)
-	}
-	hs.serverHello = serverHello
-
-	if err := hs.checkServerHelloOrHRR(); err != nil {
-		return err
-	}
-
-	hs.transcript.Write(hs.hello.marshal())
-	return nil
-}
-
-func (hs *clientHandshakeStateTLS13) processServerHello() error {
-	c := hs.c
-
-	defer func() {
-		hs.hsTimings.ProcessServerHello = hs.hsTimings.elapsedTime()
-	}()
-
-	if bytes.Equal(hs.serverHello.random, helloRetryRequestRandom) {
-		c.sendAlert(alertUnexpectedMessage)
-		return errors.New("tls: server sent two HelloRetryRequest messages")
-	}
-
-	if len(hs.serverHello.cookie) != 0 {
-		c.sendAlert(alertUnsupportedExtension)
-		return errors.New("tls: server sent a cookie in a normal ServerHello")
-	}
-
-	if hs.serverHello.selectedGroup != 0 {
-		c.sendAlert(alertDecodeError)
-		return errors.New("tls: malformed key_share extension")
-	}
-
-	if hs.serverHello.serverShare.group == 0 {
-		c.sendAlert(alertIllegalParameter)
-		return errors.New("tls: server did not send a key share")
-	}
-	if hs.serverHello.serverShare.group != clientKeySharePrivateCurveID(hs.keySharePrivate) {
-		c.sendAlert(alertIllegalParameter)
-		return errors.New("tls: server selected unsupported group")
-	}
-
-	c.handleCFEvent(CFEventTLSNegotiatedNamedKEX{
-		KEX: hs.serverHello.serverShare.group,
-	})
-
-	if !hs.serverHello.selectedIdentityPresent {
-		return nil
-	}
-
-	// Per the rules of draft-ietf-tls-esni-13, Section 6.1, the server is not
-	// permitted to resume a connection connection in the outer handshake. If
-	// ECH is rejected and the client-facing server replies with a
-	// "pre_shared_key" extension in its ServerHello, then the client MUST abort
-	// the handshake with an "illegal_parameter" alert.
-	if c.ech.offered && !c.ech.accepted {
-		c.sendAlert(alertIllegalParameter)
-		return errors.New("tls: ech: client-facing server offered PSK after ECH rejection")
-	}
-
-	if int(hs.serverHello.selectedIdentity) >= len(hs.hello.pskIdentities) {
-		c.sendAlert(alertIllegalParameter)
-		return errors.New("tls: server selected an invalid PSK")
-	}
-
-	if len(hs.hello.pskIdentities) != 1 || hs.session == nil {
-		return c.sendAlert(alertInternalError)
-	}
-	pskSuite := cipherSuiteTLS13ByID(hs.session.cipherSuite)
-	if pskSuite == nil {
-		return c.sendAlert(alertInternalError)
-	}
-	if pskSuite.hash != hs.suite.hash {
-		c.sendAlert(alertIllegalParameter)
-		return errors.New("tls: server selected an invalid PSK and cipher suite pair")
-	}
-
-	hs.usingPSK = true
-	c.didResume = true
-	c.peerCertificates = hs.session.serverCertificates
-	c.verifiedChains = hs.session.verifiedChains
-	c.ocspResponse = hs.session.ocspResponse
-	c.scts = hs.session.scts
-	return nil
-}
-
-func (hs *clientHandshakeStateTLS13) establishHandshakeKeys() error {
-	c := hs.c
-
-	var sharedKey []byte
-	if params, ok := hs.keySharePrivate.(ecdheParameters); ok {
-		sharedKey = params.SharedKey(hs.serverHello.serverShare.data)
-	} else if sk, ok := hs.keySharePrivate.(circlKem.PrivateKey); ok {
-		var err error
-		sharedKey, err = sk.Scheme().Decapsulate(sk, hs.serverHello.serverShare.data)
-		if err != nil {
-			c.sendAlert(alertIllegalParameter)
-			return fmt.Errorf("%s decaps: %w", sk.Scheme().Name(), err)
-		}
-	}
-
-	if sharedKey == nil {
-		c.sendAlert(alertIllegalParameter)
-		return fmt.Errorf("tls: invalid server key share")
-	}
-
-	earlySecret := hs.earlySecret
-	if !hs.usingPSK {
-		earlySecret = hs.suite.extract(nil, nil)
-	}
-	handshakeSecret := hs.suite.extract(sharedKey,
-		hs.suite.deriveSecret(earlySecret, "derived", nil))
-
-	clientSecret := hs.suite.deriveSecret(handshakeSecret,
-		clientHandshakeTrafficLabel, hs.transcript)
-	c.out.setTrafficSecret(hs.suite, clientSecret)
-	serverSecret := hs.suite.deriveSecret(handshakeSecret,
-		serverHandshakeTrafficLabel, hs.transcript)
-	c.in.setTrafficSecret(hs.suite, serverSecret)
-
-	err := c.config.writeKeyLog(keyLogLabelClientHandshake, hs.hello.random, clientSecret)
-	if err != nil {
-		c.sendAlert(alertInternalError)
-		return err
-	}
-	err = c.config.writeKeyLog(keyLogLabelServerHandshake, hs.hello.random, serverSecret)
-	if err != nil {
-		c.sendAlert(alertInternalError)
-		return err
-	}
-
-	hs.masterSecret = hs.suite.extract(nil,
-		hs.suite.deriveSecret(handshakeSecret, "derived", nil))
-
-	return nil
-}
-
-func (hs *clientHandshakeStateTLS13) readServerParameters() error {
-	c := hs.c
-
-	msg, err := c.readHandshake()
-	if err != nil {
-		return err
-	}
-
-	encryptedExtensions, ok := msg.(*encryptedExtensionsMsg)
-	if !ok {
-		c.sendAlert(alertUnexpectedMessage)
-		return unexpectedMessageError(encryptedExtensions, msg)
-	}
-	hs.transcript.Write(encryptedExtensions.marshal())
-
-	if err := checkALPN(hs.hello.alpnProtocols, encryptedExtensions.alpnProtocol); err != nil {
-		c.sendAlert(alertUnsupportedExtension)
-		return err
-	}
-	c.clientProtocol = encryptedExtensions.alpnProtocol
-
-	if c.ech.offered && len(encryptedExtensions.ech) > 0 {
-		if !c.ech.accepted {
-			// If the server rejects ECH, then it may send retry configurations.
-			// If present, we must check them for syntactic correctness and
-			// abort if they are not correct.
-			c.ech.retryConfigs = encryptedExtensions.ech
-			if _, err = UnmarshalECHConfigs(c.ech.retryConfigs); err != nil {
-				c.sendAlert(alertDecodeError)
-				return fmt.Errorf("tls: ech: failed to parse retry configs: %s", err)
-			}
-		} else {
-			// Retry configs must not be sent in the inner handshake.
-			c.sendAlert(alertUnsupportedExtension)
-			return errors.New("tls: ech: got retry configs after ECH acceptance")
-		}
-	}
-
-	hs.hsTimings.ReadEncryptedExtensions = hs.hsTimings.elapsedTime()
-
-	return nil
-}
-
-func (hs *clientHandshakeStateTLS13) readServerCertificate() error {
-	c := hs.c
-
-	// Either a PSK or a certificate is always used, but not both.
-	// See RFC 8446, Section 4.1.1.
-	if hs.usingPSK {
-		// Make sure the connection is still being verified whether or not this
-		// is a resumption. Resumptions currently don't reverify certificates so
-		// they don't call verifyServerCertificate. See Issue 31641.
-		if c.config.VerifyConnection != nil {
-			if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil {
-				c.sendAlert(alertBadCertificate)
-				return err
-			}
-		}
-		return nil
-	}
-
-	msg, err := c.readHandshake()
-	if err != nil {
-		return err
-	}
-
-	certReq, ok := msg.(*certificateRequestMsgTLS13)
-	if ok {
-		hs.transcript.Write(certReq.marshal())
-
-		hs.certReq = certReq
-
-		msg, err = c.readHandshake()
-		if err != nil {
-			return err
-		}
-	}
-
-	certMsg, ok := msg.(*certificateMsgTLS13)
-	if !ok {
-		c.sendAlert(alertUnexpectedMessage)
-		return unexpectedMessageError(certMsg, msg)
-	}
-	if len(certMsg.certificate.Certificate) == 0 {
-		c.sendAlert(alertDecodeError)
-		return errors.New("tls: received empty certificates message")
-	}
-	hs.transcript.Write(certMsg.marshal())
-
-	hs.hsTimings.ReadCertificate = hs.hsTimings.elapsedTime()
-
-	c.scts = certMsg.certificate.SignedCertificateTimestamps
-	c.ocspResponse = certMsg.certificate.OCSPStaple
-
-	if err := c.verifyServerCertificate(certMsg.certificate.Certificate); err != nil {
-		return err
-	}
-
-	msg, err = c.readHandshake()
-	if err != nil {
-		return err
-	}
-
-	certVerify, ok := msg.(*certificateVerifyMsg)
-	if !ok {
-		c.sendAlert(alertUnexpectedMessage)
-		return unexpectedMessageError(certVerify, msg)
-	}
-
-	// See RFC 8446, Section 4.4.3.
-	if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, c.config.supportedSignatureAlgorithms()) {
-		c.sendAlert(alertIllegalParameter)
-		return errors.New("tls: certificate used with invalid signature algorithm")
-	}
-
-	sigType, sigHash, err := typeAndHashFromSignatureScheme(certVerify.signatureAlgorithm)
-	if err != nil {
-		return c.sendAlert(alertInternalError)
-	}
-	if sigType == signaturePKCS1v15 || sigHash == crypto.SHA1 {
-		c.sendAlert(alertIllegalParameter)
-		return errors.New("tls: certificate used with invalid signature algorithm")
-	}
-	if certMsg.delegatedCredential {
-		if err := hs.processDelegatedCredentialFromServer(certMsg.certificate.DelegatedCredential, certVerify); err != nil {
-			return err // alert sent
-		}
-	}
-
-	pk := c.peerCertificates[0].PublicKey
-	if c.verifiedDC != nil {
-		pk = c.verifiedDC.cred.publicKey
-	}
-
-	signed := signedMessage(sigHash, serverSignatureContext, hs.transcript)
-	if err := verifyHandshakeSignature(sigType, pk,
-		sigHash, signed, certVerify.signature); err != nil {
-		c.sendAlert(alertDecryptError)
-		return errors.New("tls: invalid signature by the server certificate: " + err.Error())
-	}
-
-	hs.transcript.Write(certVerify.marshal())
-
-	hs.hsTimings.ReadCertificateVerify = hs.hsTimings.elapsedTime()
-
-	return nil
-}
-
-func (hs *clientHandshakeStateTLS13) readServerFinished() error {
-	c := hs.c
-
-	msg, err := c.readHandshake()
-	if err != nil {
-		return err
-	}
-
-	finished, ok := msg.(*finishedMsg)
-	if !ok {
-		c.sendAlert(alertUnexpectedMessage)
-		return unexpectedMessageError(finished, msg)
-	}
-
-	hs.hsTimings.ReadServerFinished = hs.hsTimings.elapsedTime()
-
-	expectedMAC := hs.suite.finishedHash(c.in.trafficSecret, hs.transcript)
-	if !hmac.Equal(expectedMAC, finished.verifyData) {
-		c.sendAlert(alertDecryptError)
-		return errors.New("tls: invalid server finished hash")
-	}
-
-	hs.transcript.Write(finished.marshal())
-
-	// Derive secrets that take context through the server Finished.
-
-	hs.trafficSecret = hs.suite.deriveSecret(hs.masterSecret,
-		clientApplicationTrafficLabel, hs.transcript)
-	serverSecret := hs.suite.deriveSecret(hs.masterSecret,
-		serverApplicationTrafficLabel, hs.transcript)
-	c.in.setTrafficSecret(hs.suite, serverSecret)
-
-	err = c.config.writeKeyLog(keyLogLabelClientTraffic, hs.hello.random, hs.trafficSecret)
-	if err != nil {
-		c.sendAlert(alertInternalError)
-		return err
-	}
-	err = c.config.writeKeyLog(keyLogLabelServerTraffic, hs.hello.random, serverSecret)
-	if err != nil {
-		c.sendAlert(alertInternalError)
-		return err
-	}
-
-	c.ekm = hs.suite.exportKeyingMaterial(hs.masterSecret, hs.transcript)
-
-	return nil
-}
-
-func certificateRequestInfo(certReq *certificateRequestMsgTLS13, vers uint16, ctx context.Context) *CertificateRequestInfo {
-	cri := &CertificateRequestInfo{
-		SupportsDelegatedCredential: certReq.supportDelegatedCredential,
-		SignatureSchemes:            certReq.supportedSignatureAlgorithms,
-		SignatureSchemesDC:          certReq.supportedSignatureAlgorithmsDC,
-		AcceptableCAs:               certReq.certificateAuthorities,
-		Version:                     vers,
-		ctx:                         ctx,
-	}
-
-	return cri
-}
-
-// getClientDelegatedCredential will return a Delegated Credential pair (a
-// Delegated Credential and its private key) for the given CertificateRequestInfo,
-// defaulting to the first element of cert.DelegatedCredentialPair.
-// The returned Delegated Credential could be invalid for usage in the handshake.
-// Returns an error if there are no delegated credentials or if the one found
-// cannot be used for the current connection.
-func getClientDelegatedCredential(cri *CertificateRequestInfo, cert *Certificate) (*DelegatedCredentialPair, error) {
-	if len(cert.DelegatedCredentials) == 0 {
-		return nil, errors.New("no Delegated Credential found")
-	}
-
-	for _, dcPair := range cert.DelegatedCredentials {
-		// If the client sent the signature_algorithms in the DC extension, ensure it supports
-		// schemes we can use with this delegated credential.
-		if len(cri.SignatureSchemesDC) > 0 {
-			if _, err := selectSignatureSchemeDC(VersionTLS13, dcPair.DC, cri.SignatureSchemes, cri.SignatureSchemesDC); err == nil {
-				return &dcPair, nil
-			}
-		}
-	}
-
-	// No delegated credential can be returned.
-	return nil, errors.New("no valid Delegated Credential found")
-}
-
-func (hs *clientHandshakeStateTLS13) sendClientCertificate() error {
-	c := hs.c
-
-	if hs.certReq == nil {
-		return nil
-	}
-
-	cri := certificateRequestInfo(hs.certReq, c.vers, hs.ctx)
-
-	cert, err := c.getClientCertificate(cri)
-	if err != nil {
-		return err
-	}
-
-	var dcPair *DelegatedCredentialPair
-	if hs.certReq.supportDelegatedCredential && len(hs.certReq.supportedSignatureAlgorithmsDC) > 0 {
-		// getClientDelegatedCredential selects a delegated credential that the server has advertised support for, if possible.
-		if delegatedCredentialPair, err := getClientDelegatedCredential(cri, cert); err == nil {
-			if delegatedCredentialPair.DC != nil && delegatedCredentialPair.PrivateKey != nil {
-				var err error
-				// Even if the Delegated Credential has already been marshalled, be sure it is the correct one.
-				if delegatedCredentialPair.DC.raw, err = delegatedCredentialPair.DC.Marshal(); err == nil {
-					dcPair = delegatedCredentialPair
-					cert.DelegatedCredential = dcPair.DC.raw
-				}
-			}
-		}
-	}
-
-	certMsg := new(certificateMsgTLS13)
-
-	certMsg.certificate = *cert
-	certMsg.scts = hs.certReq.scts && len(cert.SignedCertificateTimestamps) > 0
-	certMsg.ocspStapling = hs.certReq.ocspStapling && len(cert.OCSPStaple) > 0
-	certMsg.delegatedCredential = hs.certReq.supportDelegatedCredential && len(cert.DelegatedCredential) > 0
-
-	hs.transcript.Write(certMsg.marshal())
-	if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil {
-		return err
-	}
-
-	hs.hsTimings.WriteCertificate = hs.hsTimings.elapsedTime()
-
-	// If we sent an empty certificate message, skip the CertificateVerify.
-	if len(cert.Certificate) == 0 {
-		return nil
-	}
-
-	certVerifyMsg := new(certificateVerifyMsg)
-	certVerifyMsg.hasSignatureAlgorithm = true
-
-	var sigAlgorithm SignatureScheme
-	suppSigAlgo := hs.certReq.supportedSignatureAlgorithms
-	sigAlgorithm, err = selectSignatureScheme(c.vers, cert, suppSigAlgo)
-	if err != nil {
-		// getClientCertificate returned a certificate incompatible with the
-		// CertificateRequestInfo supported signature algorithms.
-		c.sendAlert(alertHandshakeFailure)
-		return err
-	}
-
-	if certMsg.delegatedCredential {
-		suppSigAlgo = hs.certReq.supportedSignatureAlgorithmsDC
-		if dcPair == nil || dcPair.DC == nil {
-			cert.DelegatedCredential = nil
-		} else {
-			sigAlgorithm = dcPair.DC.cred.expCertVerfAlgo
-			cert.PrivateKey = dcPair.PrivateKey
-		}
-	}
-
-	certVerifyMsg.signatureAlgorithm = sigAlgorithm
-
-	sigType, sigHash, err := typeAndHashFromSignatureScheme(certVerifyMsg.signatureAlgorithm)
-	if err != nil {
-		return c.sendAlert(alertInternalError)
-	}
-
-	signed := signedMessage(sigHash, clientSignatureContext, hs.transcript)
-	signOpts := crypto.SignerOpts(sigHash)
-	if sigType == signatureRSAPSS {
-		signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash}
-	}
-	sig, err := cert.PrivateKey.(crypto.Signer).Sign(c.config.rand(), signed, signOpts)
-	if err != nil {
-		c.sendAlert(alertInternalError)
-		return errors.New("tls: failed to sign handshake: " + err.Error())
-	}
-	certVerifyMsg.signature = sig
-
-	hs.transcript.Write(certVerifyMsg.marshal())
-	if _, err := c.writeRecord(recordTypeHandshake, certVerifyMsg.marshal()); err != nil {
-		return err
-	}
-
-	hs.hsTimings.WriteCertificateVerify = hs.hsTimings.elapsedTime()
-
-	return nil
-}
-
-func (hs *clientHandshakeStateTLS13) sendClientFinished() error {
-	c := hs.c
-
-	finished := &finishedMsg{
-		verifyData: hs.suite.finishedHash(c.out.trafficSecret, hs.transcript),
-	}
-
-	hs.transcript.Write(finished.marshal())
-	if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil {
-		return err
-	}
-
-	hs.hsTimings.WriteClientFinished = hs.hsTimings.elapsedTime()
-
-	c.out.setTrafficSecret(hs.suite, hs.trafficSecret)
-
-	if !c.config.SessionTicketsDisabled && c.config.ClientSessionCache != nil && !c.config.ECHEnabled {
-		c.resumptionSecret = hs.suite.deriveSecret(hs.masterSecret,
-			resumptionLabel, hs.transcript)
-	}
-
-	return nil
-}
-
-func (c *Conn) handleNewSessionTicket(msg *newSessionTicketMsgTLS13) error {
-	if !c.isClient {
-		c.sendAlert(alertUnexpectedMessage)
-		return errors.New("tls: received new session ticket from a client")
-	}
-
-	if c.config.SessionTicketsDisabled || c.config.ClientSessionCache == nil || c.config.ECHEnabled {
-		return nil
-	}
-
-	// See RFC 8446, Section 4.6.1.
-	if msg.lifetime == 0 {
-		return nil
-	}
-	lifetime := time.Duration(msg.lifetime) * time.Second
-	if lifetime > maxSessionTicketLifetime {
-		c.sendAlert(alertIllegalParameter)
-		return errors.New("tls: received a session ticket with invalid lifetime")
-	}
-
-	cipherSuite := cipherSuiteTLS13ByID(c.cipherSuite)
-	if cipherSuite == nil || c.resumptionSecret == nil {
-		return c.sendAlert(alertInternalError)
-	}
-
-	// Save the resumption_master_secret and nonce instead of deriving the PSK
-	// to do the least amount of work on NewSessionTicket messages before we
-	// know if the ticket will be used. Forward secrecy of resumed connections
-	// is guaranteed by the requirement for pskModeDHE.
-	session := &ClientSessionState{
-		sessionTicket:      msg.label,
-		vers:               c.vers,
-		cipherSuite:        c.cipherSuite,
-		masterSecret:       c.resumptionSecret,
-		serverCertificates: c.peerCertificates,
-		verifiedChains:     c.verifiedChains,
-		receivedAt:         c.config.time(),
-		nonce:              msg.nonce,
-		useBy:              c.config.time().Add(lifetime),
-		ageAdd:             msg.ageAdd,
-		ocspResponse:       c.ocspResponse,
-		scts:               c.scts,
-	}
-
-	cacheKey := clientSessionCacheKey(c.conn.RemoteAddr(), c.config)
-	c.config.ClientSessionCache.Put(cacheKey, session)
-
-	return nil
-}
-
-func (hs *clientHandshakeStateTLS13) abortIfRequired() error {
-	c := hs.c
-	if c.ech.offered && !c.ech.accepted {
-		// If ECH was rejected, then abort the handshake.
-		c.sendAlert(alertECHRequired)
-		return errors.New("tls: ech: rejected")
-	}
-	return nil
-}

+ 0 - 1927
transport/cloudflaretls/handshake_messages.go

@@ -1,1927 +0,0 @@
-// Copyright 2009 The Go Authors. 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 (
-	"fmt"
-	"strings"
-
-	"golang.org/x/crypto/cryptobyte"
-)
-
-// The marshalingFunction type is an adapter to allow the use of ordinary
-// functions as cryptobyte.MarshalingValue.
-type marshalingFunction func(b *cryptobyte.Builder) error
-
-func (f marshalingFunction) Marshal(b *cryptobyte.Builder) error {
-	return f(b)
-}
-
-// addBytesWithLength appends a sequence of bytes to the cryptobyte.Builder. If
-// the length of the sequence is not the value specified, it produces an error.
-func addBytesWithLength(b *cryptobyte.Builder, v []byte, n int) {
-	b.AddValue(marshalingFunction(func(b *cryptobyte.Builder) error {
-		if len(v) != n {
-			return fmt.Errorf("invalid value length: expected %d, got %d", n, len(v))
-		}
-		b.AddBytes(v)
-		return nil
-	}))
-}
-
-// addUint64 appends a big-endian, 64-bit value to the cryptobyte.Builder.
-func addUint64(b *cryptobyte.Builder, v uint64) {
-	b.AddUint32(uint32(v >> 32))
-	b.AddUint32(uint32(v))
-}
-
-// readUint64 decodes a big-endian, 64-bit value into out and advances over it.
-// It reports whether the read was successful.
-func readUint64(s *cryptobyte.String, out *uint64) bool {
-	var hi, lo uint32
-	if !s.ReadUint32(&hi) || !s.ReadUint32(&lo) {
-		return false
-	}
-	*out = uint64(hi)<<32 | uint64(lo)
-	return true
-}
-
-// readUint8LengthPrefixed acts like s.ReadUint8LengthPrefixed, but targets a
-// []byte instead of a cryptobyte.String.
-func readUint8LengthPrefixed(s *cryptobyte.String, out *[]byte) bool {
-	return s.ReadUint8LengthPrefixed((*cryptobyte.String)(out))
-}
-
-// readUint16LengthPrefixed acts like s.ReadUint16LengthPrefixed, but targets a
-// []byte instead of a cryptobyte.String.
-func readUint16LengthPrefixed(s *cryptobyte.String, out *[]byte) bool {
-	return s.ReadUint16LengthPrefixed((*cryptobyte.String)(out))
-}
-
-// readUint24LengthPrefixed acts like s.ReadUint24LengthPrefixed, but targets a
-// []byte instead of a cryptobyte.String.
-func readUint24LengthPrefixed(s *cryptobyte.String, out *[]byte) bool {
-	return s.ReadUint24LengthPrefixed((*cryptobyte.String)(out))
-}
-
-type clientHelloMsg struct {
-	raw                              []byte
-	vers                             uint16
-	random                           []byte
-	sessionId                        []byte
-	cipherSuites                     []uint16
-	compressionMethods               []uint8
-	serverName                       string
-	ocspStapling                     bool
-	supportedCurves                  []CurveID
-	supportedPoints                  []uint8
-	ticketSupported                  bool
-	sessionTicket                    []uint8
-	supportedSignatureAlgorithms     []SignatureScheme
-	supportedSignatureAlgorithmsCert []SignatureScheme
-	supportedSignatureAlgorithmsDC   []SignatureScheme
-	secureRenegotiationSupported     bool
-	secureRenegotiation              []byte
-	delegatedCredentialSupported     bool
-	alpnProtocols                    []string
-	scts                             bool
-	supportedVersions                []uint16
-	cookie                           []byte
-	keyShares                        []keyShare
-	earlyData                        bool
-	pskModes                         []uint8
-	pskIdentities                    []pskIdentity
-	pskBinders                       [][]byte
-	ech                              []byte
-}
-
-func (m *clientHelloMsg) marshal() []byte {
-	if m.raw != nil {
-		return m.raw
-	}
-
-	var b cryptobyte.Builder
-	b.AddUint8(typeClientHello)
-	b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
-		b.AddUint16(m.vers)
-		addBytesWithLength(b, m.random, 32)
-		b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
-			b.AddBytes(m.sessionId)
-		})
-		b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-			for _, suite := range m.cipherSuites {
-				b.AddUint16(suite)
-			}
-		})
-		b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
-			b.AddBytes(m.compressionMethods)
-		})
-
-		// If extensions aren't present, omit them.
-		var extensionsPresent bool
-		bWithoutExtensions := *b
-
-		b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-			if len(m.ech) > 0 {
-				// draft-ietf-tls-esni-13, "encrypted_client_hello"
-				b.AddUint16(extensionECH)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddBytes(m.ech)
-				})
-			}
-			if len(m.serverName) > 0 {
-				// RFC 6066, Section 3
-				b.AddUint16(extensionServerName)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-						b.AddUint8(0) // name_type = host_name
-						b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-							b.AddBytes([]byte(m.serverName))
-						})
-					})
-				})
-			}
-			if m.ocspStapling {
-				// RFC 4366, Section 3.6
-				b.AddUint16(extensionStatusRequest)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint8(1)  // status_type = ocsp
-					b.AddUint16(0) // empty responder_id_list
-					b.AddUint16(0) // empty request_extensions
-				})
-			}
-			if len(m.supportedCurves) > 0 {
-				// RFC 4492, sections 5.1.1 and RFC 8446, Section 4.2.7
-				b.AddUint16(extensionSupportedCurves)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-						for _, curve := range m.supportedCurves {
-							b.AddUint16(uint16(curve))
-						}
-					})
-				})
-			}
-			if len(m.supportedPoints) > 0 {
-				// RFC 4492, Section 5.1.2
-				b.AddUint16(extensionSupportedPoints)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
-						b.AddBytes(m.supportedPoints)
-					})
-				})
-			}
-			if m.ticketSupported {
-				// RFC 5077, Section 3.2
-				b.AddUint16(extensionSessionTicket)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddBytes(m.sessionTicket)
-				})
-			}
-			if len(m.supportedSignatureAlgorithms) > 0 {
-				// RFC 5246, Section 7.4.1.4.1
-				b.AddUint16(extensionSignatureAlgorithms)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-						for _, sigAlgo := range m.supportedSignatureAlgorithms {
-							b.AddUint16(uint16(sigAlgo))
-						}
-					})
-				})
-			}
-			if len(m.supportedSignatureAlgorithmsCert) > 0 {
-				// RFC 8446, Section 4.2.3
-				b.AddUint16(extensionSignatureAlgorithmsCert)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-						for _, sigAlgo := range m.supportedSignatureAlgorithmsCert {
-							b.AddUint16(uint16(sigAlgo))
-						}
-					})
-				})
-			}
-			if m.secureRenegotiationSupported {
-				// RFC 5746, Section 3.2
-				b.AddUint16(extensionRenegotiationInfo)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
-						b.AddBytes(m.secureRenegotiation)
-					})
-				})
-			}
-			if m.delegatedCredentialSupported {
-				if len(m.supportedSignatureAlgorithmsDC) > 0 {
-					// Draft: https://tools.ietf.org/html/draft-ietf-tls-subcerts-10
-					b.AddUint16(extensionDelegatedCredentials)
-					b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-						b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-							for _, sigAlgo := range m.supportedSignatureAlgorithmsDC {
-								b.AddUint16(uint16(sigAlgo))
-							}
-						})
-					})
-				}
-			}
-			if len(m.alpnProtocols) > 0 {
-				// RFC 7301, Section 3.1
-				b.AddUint16(extensionALPN)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-						for _, proto := range m.alpnProtocols {
-							b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
-								b.AddBytes([]byte(proto))
-							})
-						}
-					})
-				})
-			}
-			if m.scts {
-				// RFC 6962, Section 3.3.1
-				b.AddUint16(extensionSCT)
-				b.AddUint16(0) // empty extension_data
-			}
-			if len(m.supportedVersions) > 0 {
-				// RFC 8446, Section 4.2.1
-				b.AddUint16(extensionSupportedVersions)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
-						for _, vers := range m.supportedVersions {
-							b.AddUint16(vers)
-						}
-					})
-				})
-			}
-			if len(m.cookie) > 0 {
-				// RFC 8446, Section 4.2.2
-				b.AddUint16(extensionCookie)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-						b.AddBytes(m.cookie)
-					})
-				})
-			}
-			if len(m.keyShares) > 0 {
-				// RFC 8446, Section 4.2.8
-				b.AddUint16(extensionKeyShare)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-						for _, ks := range m.keyShares {
-							b.AddUint16(uint16(ks.group))
-							b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-								b.AddBytes(ks.data)
-							})
-						}
-					})
-				})
-			}
-			if m.earlyData {
-				// RFC 8446, Section 4.2.10
-				b.AddUint16(extensionEarlyData)
-				b.AddUint16(0) // empty extension_data
-			}
-			if len(m.pskModes) > 0 {
-				// RFC 8446, Section 4.2.9
-				b.AddUint16(extensionPSKModes)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
-						b.AddBytes(m.pskModes)
-					})
-				})
-			}
-			if len(m.pskIdentities) > 0 { // pre_shared_key must be the last extension
-				// RFC 8446, Section 4.2.11
-				b.AddUint16(extensionPreSharedKey)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-						for _, psk := range m.pskIdentities {
-							b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-								b.AddBytes(psk.label)
-							})
-							b.AddUint32(psk.obfuscatedTicketAge)
-						}
-					})
-					b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-						for _, binder := range m.pskBinders {
-							b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
-								b.AddBytes(binder)
-							})
-						}
-					})
-				})
-			}
-
-			extensionsPresent = len(b.BytesOrPanic()) > 2
-		})
-
-		if !extensionsPresent {
-			*b = bWithoutExtensions
-		}
-	})
-
-	m.raw = b.BytesOrPanic()
-	return m.raw
-}
-
-// marshalWithoutBinders returns the ClientHello through the
-// PreSharedKeyExtension.identities field, according to RFC 8446, Section
-// 4.2.11.2. Note that m.pskBinders must be set to slices of the correct length.
-func (m *clientHelloMsg) marshalWithoutBinders() []byte {
-	bindersLen := 2 // uint16 length prefix
-	for _, binder := range m.pskBinders {
-		bindersLen += 1 // uint8 length prefix
-		bindersLen += len(binder)
-	}
-
-	fullMessage := m.marshal()
-	return fullMessage[:len(fullMessage)-bindersLen]
-}
-
-// updateBinders updates the m.pskBinders field, if necessary updating the
-// cached marshaled representation. The supplied binders must have the same
-// length as the current m.pskBinders.
-func (m *clientHelloMsg) updateBinders(pskBinders [][]byte) {
-	if len(pskBinders) != len(m.pskBinders) {
-		panic("tls: internal error: pskBinders length mismatch")
-	}
-	for i := range m.pskBinders {
-		if len(pskBinders[i]) != len(m.pskBinders[i]) {
-			panic("tls: internal error: pskBinders length mismatch")
-		}
-	}
-	m.pskBinders = pskBinders
-	if m.raw != nil {
-		lenWithoutBinders := len(m.marshalWithoutBinders())
-		b := cryptobyte.NewFixedBuilder(m.raw[:lenWithoutBinders])
-		b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-			for _, binder := range m.pskBinders {
-				b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddBytes(binder)
-				})
-			}
-		})
-		if out, err := b.Bytes(); err != nil || len(out) != len(m.raw) {
-			panic("tls: internal error: failed to update binders")
-		}
-	}
-}
-
-func (m *clientHelloMsg) unmarshal(data []byte) bool {
-	*m = clientHelloMsg{raw: data}
-	s := cryptobyte.String(data)
-
-	if !s.Skip(4) || // message type and uint24 length field
-		!s.ReadUint16(&m.vers) || !s.ReadBytes(&m.random, 32) ||
-		!readUint8LengthPrefixed(&s, &m.sessionId) {
-		return false
-	}
-
-	var cipherSuites cryptobyte.String
-	if !s.ReadUint16LengthPrefixed(&cipherSuites) {
-		return false
-	}
-	m.cipherSuites = []uint16{}
-	m.secureRenegotiationSupported = false
-	for !cipherSuites.Empty() {
-		var suite uint16
-		if !cipherSuites.ReadUint16(&suite) {
-			return false
-		}
-		if suite == scsvRenegotiation {
-			m.secureRenegotiationSupported = true
-		}
-		m.cipherSuites = append(m.cipherSuites, suite)
-	}
-
-	if !readUint8LengthPrefixed(&s, &m.compressionMethods) {
-		return false
-	}
-
-	if s.Empty() {
-		// ClientHello is optionally followed by extension data
-		return true
-	}
-
-	var extensions cryptobyte.String
-	if !s.ReadUint16LengthPrefixed(&extensions) || !s.Empty() {
-		return false
-	}
-
-	for !extensions.Empty() {
-		var extension uint16
-		var extData cryptobyte.String
-		if !extensions.ReadUint16(&extension) ||
-			!extensions.ReadUint16LengthPrefixed(&extData) {
-			return false
-		}
-
-		switch extension {
-		case extensionECH:
-			// draft-ietf-tls-esni-13, "encrypted_client_hello"
-			if len(extData) == 0 ||
-				!extData.ReadBytes(&m.ech, len(extData)) {
-				return false
-			}
-		case extensionServerName:
-			// RFC 6066, Section 3
-			var nameList cryptobyte.String
-			if !extData.ReadUint16LengthPrefixed(&nameList) || nameList.Empty() {
-				return false
-			}
-			for !nameList.Empty() {
-				var nameType uint8
-				var serverName cryptobyte.String
-				if !nameList.ReadUint8(&nameType) ||
-					!nameList.ReadUint16LengthPrefixed(&serverName) ||
-					serverName.Empty() {
-					return false
-				}
-				if nameType != 0 {
-					continue
-				}
-				if len(m.serverName) != 0 {
-					// Multiple names of the same name_type are prohibited.
-					return false
-				}
-				m.serverName = string(serverName)
-				// An SNI value may not include a trailing dot.
-				if strings.HasSuffix(m.serverName, ".") {
-					return false
-				}
-			}
-		case extensionStatusRequest:
-			// RFC 4366, Section 3.6
-			var statusType uint8
-			var ignored cryptobyte.String
-			if !extData.ReadUint8(&statusType) ||
-				!extData.ReadUint16LengthPrefixed(&ignored) ||
-				!extData.ReadUint16LengthPrefixed(&ignored) {
-				return false
-			}
-			m.ocspStapling = statusType == statusTypeOCSP
-		case extensionSupportedCurves:
-			// RFC 4492, sections 5.1.1 and RFC 8446, Section 4.2.7
-			var curves cryptobyte.String
-			if !extData.ReadUint16LengthPrefixed(&curves) || curves.Empty() {
-				return false
-			}
-			for !curves.Empty() {
-				var curve uint16
-				if !curves.ReadUint16(&curve) {
-					return false
-				}
-				m.supportedCurves = append(m.supportedCurves, CurveID(curve))
-			}
-		case extensionSupportedPoints:
-			// RFC 4492, Section 5.1.2
-			if !readUint8LengthPrefixed(&extData, &m.supportedPoints) ||
-				len(m.supportedPoints) == 0 {
-				return false
-			}
-		case extensionSessionTicket:
-			// RFC 5077, Section 3.2
-			m.ticketSupported = true
-			extData.ReadBytes(&m.sessionTicket, len(extData))
-		case extensionSignatureAlgorithms:
-			// RFC 5246, Section 7.4.1.4.1
-			var sigAndAlgs cryptobyte.String
-			if !extData.ReadUint16LengthPrefixed(&sigAndAlgs) || sigAndAlgs.Empty() {
-				return false
-			}
-			for !sigAndAlgs.Empty() {
-				var sigAndAlg uint16
-				if !sigAndAlgs.ReadUint16(&sigAndAlg) {
-					return false
-				}
-				m.supportedSignatureAlgorithms = append(
-					m.supportedSignatureAlgorithms, SignatureScheme(sigAndAlg))
-			}
-		case extensionSignatureAlgorithmsCert:
-			// RFC 8446, Section 4.2.3
-			var sigAndAlgs cryptobyte.String
-			if !extData.ReadUint16LengthPrefixed(&sigAndAlgs) || sigAndAlgs.Empty() {
-				return false
-			}
-			for !sigAndAlgs.Empty() {
-				var sigAndAlg uint16
-				if !sigAndAlgs.ReadUint16(&sigAndAlg) {
-					return false
-				}
-				m.supportedSignatureAlgorithmsCert = append(
-					m.supportedSignatureAlgorithmsCert, SignatureScheme(sigAndAlg))
-			}
-		case extensionRenegotiationInfo:
-			// RFC 5746, Section 3.2
-			if !readUint8LengthPrefixed(&extData, &m.secureRenegotiation) {
-				return false
-			}
-			m.secureRenegotiationSupported = true
-		case extensionALPN:
-			// RFC 7301, Section 3.1
-			var protoList cryptobyte.String
-			if !extData.ReadUint16LengthPrefixed(&protoList) || protoList.Empty() {
-				return false
-			}
-			for !protoList.Empty() {
-				var proto cryptobyte.String
-				if !protoList.ReadUint8LengthPrefixed(&proto) || proto.Empty() {
-					return false
-				}
-				m.alpnProtocols = append(m.alpnProtocols, string(proto))
-			}
-		case extensionSCT:
-			// RFC 6962, Section 3.3.1
-			m.scts = true
-		case extensionSupportedVersions:
-			// RFC 8446, Section 4.2.1
-			var versList cryptobyte.String
-			if !extData.ReadUint8LengthPrefixed(&versList) || versList.Empty() {
-				return false
-			}
-			for !versList.Empty() {
-				var vers uint16
-				if !versList.ReadUint16(&vers) {
-					return false
-				}
-				m.supportedVersions = append(m.supportedVersions, vers)
-			}
-		case extensionCookie:
-			// RFC 8446, Section 4.2.2
-			if !readUint16LengthPrefixed(&extData, &m.cookie) ||
-				len(m.cookie) == 0 {
-				return false
-			}
-		case extensionDelegatedCredentials:
-			var sigAndAlgs cryptobyte.String
-			if !extData.ReadUint16LengthPrefixed(&sigAndAlgs) || sigAndAlgs.Empty() {
-				return false
-			}
-			for !sigAndAlgs.Empty() {
-				var sigAndAlg uint16
-				if !sigAndAlgs.ReadUint16(&sigAndAlg) {
-					return false
-				}
-				m.supportedSignatureAlgorithmsDC = append(
-					m.supportedSignatureAlgorithmsDC, SignatureScheme(sigAndAlg))
-			}
-			m.delegatedCredentialSupported = true
-		case extensionKeyShare:
-			// RFC 8446, Section 4.2.8
-			var clientShares cryptobyte.String
-			if !extData.ReadUint16LengthPrefixed(&clientShares) {
-				return false
-			}
-			for !clientShares.Empty() {
-				var ks keyShare
-				if !clientShares.ReadUint16((*uint16)(&ks.group)) ||
-					!readUint16LengthPrefixed(&clientShares, &ks.data) ||
-					len(ks.data) == 0 {
-					return false
-				}
-				m.keyShares = append(m.keyShares, ks)
-			}
-		case extensionEarlyData:
-			// RFC 8446, Section 4.2.10
-			m.earlyData = true
-		case extensionPSKModes:
-			// RFC 8446, Section 4.2.9
-			if !readUint8LengthPrefixed(&extData, &m.pskModes) {
-				return false
-			}
-		case extensionPreSharedKey:
-			// RFC 8446, Section 4.2.11
-			if !extensions.Empty() {
-				return false // pre_shared_key must be the last extension
-			}
-			var identities cryptobyte.String
-			if !extData.ReadUint16LengthPrefixed(&identities) || identities.Empty() {
-				return false
-			}
-			for !identities.Empty() {
-				var psk pskIdentity
-				if !readUint16LengthPrefixed(&identities, &psk.label) ||
-					!identities.ReadUint32(&psk.obfuscatedTicketAge) ||
-					len(psk.label) == 0 {
-					return false
-				}
-				m.pskIdentities = append(m.pskIdentities, psk)
-			}
-			var binders cryptobyte.String
-			if !extData.ReadUint16LengthPrefixed(&binders) || binders.Empty() {
-				return false
-			}
-			for !binders.Empty() {
-				var binder []byte
-				if !readUint8LengthPrefixed(&binders, &binder) ||
-					len(binder) == 0 {
-					return false
-				}
-				m.pskBinders = append(m.pskBinders, binder)
-			}
-		default:
-			// Ignore unknown extensions.
-			continue
-		}
-
-		if !extData.Empty() {
-			return false
-		}
-	}
-
-	return true
-}
-
-type serverHelloMsg struct {
-	raw                          []byte
-	vers                         uint16
-	random                       []byte
-	sessionId                    []byte
-	cipherSuite                  uint16
-	compressionMethod            uint8
-	ocspStapling                 bool
-	ticketSupported              bool
-	secureRenegotiationSupported bool
-	secureRenegotiation          []byte
-	alpnProtocol                 string
-	scts                         [][]byte
-	supportedVersion             uint16
-	serverShare                  keyShare
-	selectedIdentityPresent      bool
-	selectedIdentity             uint16
-	supportedPoints              []uint8
-
-	// HelloRetryRequest extensions
-	cookie        []byte
-	selectedGroup CurveID
-	ech           []byte
-}
-
-func (m *serverHelloMsg) marshal() []byte {
-	if m.raw != nil {
-		return m.raw
-	}
-
-	var b cryptobyte.Builder
-	b.AddUint8(typeServerHello)
-	b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
-		b.AddUint16(m.vers)
-		addBytesWithLength(b, m.random, 32)
-		b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
-			b.AddBytes(m.sessionId)
-		})
-		b.AddUint16(m.cipherSuite)
-		b.AddUint8(m.compressionMethod)
-
-		// If extensions aren't present, omit them.
-		var extensionsPresent bool
-		bWithoutExtensions := *b
-
-		b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-			if m.ocspStapling {
-				b.AddUint16(extensionStatusRequest)
-				b.AddUint16(0) // empty extension_data
-			}
-			if m.ticketSupported {
-				b.AddUint16(extensionSessionTicket)
-				b.AddUint16(0) // empty extension_data
-			}
-			if m.secureRenegotiationSupported {
-				b.AddUint16(extensionRenegotiationInfo)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
-						b.AddBytes(m.secureRenegotiation)
-					})
-				})
-			}
-			if len(m.alpnProtocol) > 0 {
-				b.AddUint16(extensionALPN)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-						b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
-							b.AddBytes([]byte(m.alpnProtocol))
-						})
-					})
-				})
-			}
-			if len(m.scts) > 0 {
-				b.AddUint16(extensionSCT)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-						for _, sct := range m.scts {
-							b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-								b.AddBytes(sct)
-							})
-						}
-					})
-				})
-			}
-			if m.supportedVersion != 0 {
-				b.AddUint16(extensionSupportedVersions)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint16(m.supportedVersion)
-				})
-			}
-			if m.serverShare.group != 0 {
-				b.AddUint16(extensionKeyShare)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint16(uint16(m.serverShare.group))
-					b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-						b.AddBytes(m.serverShare.data)
-					})
-				})
-			}
-			if m.selectedIdentityPresent {
-				b.AddUint16(extensionPreSharedKey)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint16(m.selectedIdentity)
-				})
-			}
-
-			if len(m.cookie) > 0 {
-				b.AddUint16(extensionCookie)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-						b.AddBytes(m.cookie)
-					})
-				})
-			}
-			if m.selectedGroup != 0 {
-				b.AddUint16(extensionKeyShare)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint16(uint16(m.selectedGroup))
-				})
-			}
-			if len(m.supportedPoints) > 0 {
-				b.AddUint16(extensionSupportedPoints)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
-						b.AddBytes(m.supportedPoints)
-					})
-				})
-			}
-			if len(m.ech) > 0 {
-				// draft-ietf-tls-esni-13, "encrypted_client_hello"
-				b.AddUint16(extensionECH)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddBytes(m.ech)
-				})
-			}
-
-			extensionsPresent = len(b.BytesOrPanic()) > 2
-		})
-
-		if !extensionsPresent {
-			*b = bWithoutExtensions
-		}
-	})
-
-	m.raw = b.BytesOrPanic()
-	return m.raw
-}
-
-func (m *serverHelloMsg) unmarshal(data []byte) bool {
-	*m = serverHelloMsg{raw: data}
-	s := cryptobyte.String(data)
-
-	if !s.Skip(4) || // message type and uint24 length field
-		!s.ReadUint16(&m.vers) || !s.ReadBytes(&m.random, 32) ||
-		!readUint8LengthPrefixed(&s, &m.sessionId) ||
-		!s.ReadUint16(&m.cipherSuite) ||
-		!s.ReadUint8(&m.compressionMethod) {
-		return false
-	}
-
-	if s.Empty() {
-		// ServerHello is optionally followed by extension data
-		return true
-	}
-
-	var extensions cryptobyte.String
-	if !s.ReadUint16LengthPrefixed(&extensions) || !s.Empty() {
-		return false
-	}
-
-	for !extensions.Empty() {
-		var extension uint16
-		var extData cryptobyte.String
-		if !extensions.ReadUint16(&extension) ||
-			!extensions.ReadUint16LengthPrefixed(&extData) {
-			return false
-		}
-
-		switch extension {
-		case extensionStatusRequest:
-			m.ocspStapling = true
-		case extensionSessionTicket:
-			m.ticketSupported = true
-		case extensionRenegotiationInfo:
-			if !readUint8LengthPrefixed(&extData, &m.secureRenegotiation) {
-				return false
-			}
-			m.secureRenegotiationSupported = true
-		case extensionALPN:
-			var protoList cryptobyte.String
-			if !extData.ReadUint16LengthPrefixed(&protoList) || protoList.Empty() {
-				return false
-			}
-			var proto cryptobyte.String
-			if !protoList.ReadUint8LengthPrefixed(&proto) ||
-				proto.Empty() || !protoList.Empty() {
-				return false
-			}
-			m.alpnProtocol = string(proto)
-		case extensionSCT:
-			var sctList cryptobyte.String
-			if !extData.ReadUint16LengthPrefixed(&sctList) || sctList.Empty() {
-				return false
-			}
-			for !sctList.Empty() {
-				var sct []byte
-				if !readUint16LengthPrefixed(&sctList, &sct) ||
-					len(sct) == 0 {
-					return false
-				}
-				m.scts = append(m.scts, sct)
-			}
-		case extensionSupportedVersions:
-			if !extData.ReadUint16(&m.supportedVersion) {
-				return false
-			}
-		case extensionCookie:
-			if !readUint16LengthPrefixed(&extData, &m.cookie) ||
-				len(m.cookie) == 0 {
-				return false
-			}
-		case extensionKeyShare:
-			// This extension has different formats in SH and HRR, accept either
-			// and let the handshake logic decide. See RFC 8446, Section 4.2.8.
-			if len(extData) == 2 {
-				if !extData.ReadUint16((*uint16)(&m.selectedGroup)) {
-					return false
-				}
-			} else {
-				if !extData.ReadUint16((*uint16)(&m.serverShare.group)) ||
-					!readUint16LengthPrefixed(&extData, &m.serverShare.data) {
-					return false
-				}
-			}
-		case extensionPreSharedKey:
-			m.selectedIdentityPresent = true
-			if !extData.ReadUint16(&m.selectedIdentity) {
-				return false
-			}
-		case extensionSupportedPoints:
-			// RFC 4492, Section 5.1.2
-			if !readUint8LengthPrefixed(&extData, &m.supportedPoints) ||
-				len(m.supportedPoints) == 0 {
-				return false
-			}
-		case extensionECH:
-			// draft-ietf-tls-esni-13, "encrypted_client_hello"
-			if !extData.ReadBytes(&m.ech, len(extData)) {
-				return false
-			}
-		default:
-			// Ignore unknown extensions.
-			continue
-		}
-
-		if !extData.Empty() {
-			return false
-		}
-	}
-
-	return true
-}
-
-type encryptedExtensionsMsg struct {
-	raw          []byte
-	alpnProtocol string
-	ech          []byte
-}
-
-func (m *encryptedExtensionsMsg) marshal() []byte {
-	if m.raw != nil {
-		return m.raw
-	}
-
-	var b cryptobyte.Builder
-	b.AddUint8(typeEncryptedExtensions)
-	b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
-		b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-			if len(m.alpnProtocol) > 0 {
-				b.AddUint16(extensionALPN)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-						b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
-							b.AddBytes([]byte(m.alpnProtocol))
-						})
-					})
-				})
-			}
-			if len(m.ech) > 0 {
-				// draft-ietf-tls-esni-13, "encrypted_client_hello"
-				b.AddUint16(extensionECH)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					// If the client-facing server rejects ECH, then it may
-					// sends retry configurations here.
-					b.AddBytes(m.ech)
-				})
-			}
-		})
-	})
-
-	m.raw = b.BytesOrPanic()
-	return m.raw
-}
-
-func (m *encryptedExtensionsMsg) unmarshal(data []byte) bool {
-	*m = encryptedExtensionsMsg{raw: data}
-	s := cryptobyte.String(data)
-
-	var extensions cryptobyte.String
-	if !s.Skip(4) || // message type and uint24 length field
-		!s.ReadUint16LengthPrefixed(&extensions) || !s.Empty() {
-		return false
-	}
-
-	for !extensions.Empty() {
-		var extension uint16
-		var extData cryptobyte.String
-		if !extensions.ReadUint16(&extension) ||
-			!extensions.ReadUint16LengthPrefixed(&extData) {
-			return false
-		}
-
-		switch extension {
-		case extensionALPN:
-			var protoList cryptobyte.String
-			if !extData.ReadUint16LengthPrefixed(&protoList) || protoList.Empty() {
-				return false
-			}
-			var proto cryptobyte.String
-			if !protoList.ReadUint8LengthPrefixed(&proto) ||
-				proto.Empty() || !protoList.Empty() {
-				return false
-			}
-			m.alpnProtocol = string(proto)
-		case extensionECH:
-			// draft-ietf-tls-esni-13
-			if !extData.ReadBytes(&m.ech, len(extData)) {
-				return false
-			}
-		default:
-			// Ignore unknown extensions.
-			continue
-		}
-
-		if !extData.Empty() {
-			return false
-		}
-	}
-
-	return true
-}
-
-type endOfEarlyDataMsg struct{}
-
-func (m *endOfEarlyDataMsg) marshal() []byte {
-	x := make([]byte, 4)
-	x[0] = typeEndOfEarlyData
-	return x
-}
-
-func (m *endOfEarlyDataMsg) unmarshal(data []byte) bool {
-	return len(data) == 4
-}
-
-type keyUpdateMsg struct {
-	raw             []byte
-	updateRequested bool
-}
-
-func (m *keyUpdateMsg) marshal() []byte {
-	if m.raw != nil {
-		return m.raw
-	}
-
-	var b cryptobyte.Builder
-	b.AddUint8(typeKeyUpdate)
-	b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
-		if m.updateRequested {
-			b.AddUint8(1)
-		} else {
-			b.AddUint8(0)
-		}
-	})
-
-	m.raw = b.BytesOrPanic()
-	return m.raw
-}
-
-func (m *keyUpdateMsg) unmarshal(data []byte) bool {
-	m.raw = data
-	s := cryptobyte.String(data)
-
-	var updateRequested uint8
-	if !s.Skip(4) || // message type and uint24 length field
-		!s.ReadUint8(&updateRequested) || !s.Empty() {
-		return false
-	}
-	switch updateRequested {
-	case 0:
-		m.updateRequested = false
-	case 1:
-		m.updateRequested = true
-	default:
-		return false
-	}
-	return true
-}
-
-type newSessionTicketMsgTLS13 struct {
-	raw          []byte
-	lifetime     uint32
-	ageAdd       uint32
-	nonce        []byte
-	label        []byte
-	maxEarlyData uint32
-}
-
-func (m *newSessionTicketMsgTLS13) marshal() []byte {
-	if m.raw != nil {
-		return m.raw
-	}
-
-	var b cryptobyte.Builder
-	b.AddUint8(typeNewSessionTicket)
-	b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
-		b.AddUint32(m.lifetime)
-		b.AddUint32(m.ageAdd)
-		b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
-			b.AddBytes(m.nonce)
-		})
-		b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-			b.AddBytes(m.label)
-		})
-
-		b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-			if m.maxEarlyData > 0 {
-				b.AddUint16(extensionEarlyData)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint32(m.maxEarlyData)
-				})
-			}
-		})
-	})
-
-	m.raw = b.BytesOrPanic()
-	return m.raw
-}
-
-func (m *newSessionTicketMsgTLS13) unmarshal(data []byte) bool {
-	*m = newSessionTicketMsgTLS13{raw: data}
-	s := cryptobyte.String(data)
-
-	var extensions cryptobyte.String
-	if !s.Skip(4) || // message type and uint24 length field
-		!s.ReadUint32(&m.lifetime) ||
-		!s.ReadUint32(&m.ageAdd) ||
-		!readUint8LengthPrefixed(&s, &m.nonce) ||
-		!readUint16LengthPrefixed(&s, &m.label) ||
-		!s.ReadUint16LengthPrefixed(&extensions) ||
-		!s.Empty() {
-		return false
-	}
-
-	for !extensions.Empty() {
-		var extension uint16
-		var extData cryptobyte.String
-		if !extensions.ReadUint16(&extension) ||
-			!extensions.ReadUint16LengthPrefixed(&extData) {
-			return false
-		}
-
-		switch extension {
-		case extensionEarlyData:
-			if !extData.ReadUint32(&m.maxEarlyData) {
-				return false
-			}
-		default:
-			// Ignore unknown extensions.
-			continue
-		}
-
-		if !extData.Empty() {
-			return false
-		}
-	}
-
-	return true
-}
-
-type certificateRequestMsgTLS13 struct {
-	raw                              []byte
-	ocspStapling                     bool
-	scts                             bool
-	supportDelegatedCredential       bool
-	supportedSignatureAlgorithms     []SignatureScheme
-	supportedSignatureAlgorithmsDC   []SignatureScheme
-	supportedSignatureAlgorithmsCert []SignatureScheme
-	certificateAuthorities           [][]byte
-}
-
-func (m *certificateRequestMsgTLS13) marshal() []byte {
-	if m.raw != nil {
-		return m.raw
-	}
-
-	var b cryptobyte.Builder
-	b.AddUint8(typeCertificateRequest)
-	b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
-		// certificate_request_context (SHALL be zero length unless used for
-		// post-handshake authentication)
-		b.AddUint8(0)
-
-		b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-			if m.ocspStapling {
-				b.AddUint16(extensionStatusRequest)
-				b.AddUint16(0) // empty extension_data
-			}
-			if m.scts {
-				// RFC 8446, Section 4.4.2.1 makes no mention of
-				// signed_certificate_timestamp in CertificateRequest, but
-				// "Extensions in the Certificate message from the client MUST
-				// correspond to extensions in the CertificateRequest message
-				// from the server." and it appears in the table in Section 4.2.
-				b.AddUint16(extensionSCT)
-				b.AddUint16(0) // empty extension_data
-			}
-			if m.supportDelegatedCredential {
-				if len(m.supportedSignatureAlgorithmsDC) > 0 {
-					// Draft: https://tools.ietf.org/html/draft-ietf-tls-subcerts-10
-					b.AddUint16(extensionDelegatedCredentials)
-					b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-						b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-							for _, sigAlgo := range m.supportedSignatureAlgorithmsDC {
-								b.AddUint16(uint16(sigAlgo))
-							}
-						})
-					})
-				}
-			}
-			if len(m.supportedSignatureAlgorithms) > 0 {
-				b.AddUint16(extensionSignatureAlgorithms)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-						for _, sigAlgo := range m.supportedSignatureAlgorithms {
-							b.AddUint16(uint16(sigAlgo))
-						}
-					})
-				})
-			}
-			if len(m.supportedSignatureAlgorithmsCert) > 0 {
-				b.AddUint16(extensionSignatureAlgorithmsCert)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-						for _, sigAlgo := range m.supportedSignatureAlgorithmsCert {
-							b.AddUint16(uint16(sigAlgo))
-						}
-					})
-				})
-			}
-			if len(m.certificateAuthorities) > 0 {
-				b.AddUint16(extensionCertificateAuthorities)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-						for _, ca := range m.certificateAuthorities {
-							b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-								b.AddBytes(ca)
-							})
-						}
-					})
-				})
-			}
-		})
-	})
-
-	m.raw = b.BytesOrPanic()
-	return m.raw
-}
-
-func (m *certificateRequestMsgTLS13) unmarshal(data []byte) bool {
-	*m = certificateRequestMsgTLS13{raw: data}
-	s := cryptobyte.String(data)
-
-	var context, extensions cryptobyte.String
-	if !s.Skip(4) || // message type and uint24 length field
-		!s.ReadUint8LengthPrefixed(&context) || !context.Empty() ||
-		!s.ReadUint16LengthPrefixed(&extensions) ||
-		!s.Empty() {
-		return false
-	}
-
-	for !extensions.Empty() {
-		var extension uint16
-		var extData cryptobyte.String
-		if !extensions.ReadUint16(&extension) ||
-			!extensions.ReadUint16LengthPrefixed(&extData) {
-			return false
-		}
-
-		switch extension {
-		case extensionStatusRequest:
-			m.ocspStapling = true
-		case extensionSCT:
-			m.scts = true
-		case extensionDelegatedCredentials:
-			var sigAndAlgs cryptobyte.String
-			if !extData.ReadUint16LengthPrefixed(&sigAndAlgs) || sigAndAlgs.Empty() {
-				return false
-			}
-			for !sigAndAlgs.Empty() {
-				var sigAndAlg uint16
-				if !sigAndAlgs.ReadUint16(&sigAndAlg) {
-					return false
-				}
-				m.supportedSignatureAlgorithmsDC = append(
-					m.supportedSignatureAlgorithmsDC, SignatureScheme(sigAndAlg))
-			}
-			m.supportDelegatedCredential = true
-		case extensionSignatureAlgorithms:
-			var sigAndAlgs cryptobyte.String
-			if !extData.ReadUint16LengthPrefixed(&sigAndAlgs) || sigAndAlgs.Empty() {
-				return false
-			}
-			for !sigAndAlgs.Empty() {
-				var sigAndAlg uint16
-				if !sigAndAlgs.ReadUint16(&sigAndAlg) {
-					return false
-				}
-				m.supportedSignatureAlgorithms = append(
-					m.supportedSignatureAlgorithms, SignatureScheme(sigAndAlg))
-			}
-		case extensionSignatureAlgorithmsCert:
-			var sigAndAlgs cryptobyte.String
-			if !extData.ReadUint16LengthPrefixed(&sigAndAlgs) || sigAndAlgs.Empty() {
-				return false
-			}
-			for !sigAndAlgs.Empty() {
-				var sigAndAlg uint16
-				if !sigAndAlgs.ReadUint16(&sigAndAlg) {
-					return false
-				}
-				m.supportedSignatureAlgorithmsCert = append(
-					m.supportedSignatureAlgorithmsCert, SignatureScheme(sigAndAlg))
-			}
-		case extensionCertificateAuthorities:
-			var auths cryptobyte.String
-			if !extData.ReadUint16LengthPrefixed(&auths) || auths.Empty() {
-				return false
-			}
-			for !auths.Empty() {
-				var ca []byte
-				if !readUint16LengthPrefixed(&auths, &ca) || len(ca) == 0 {
-					return false
-				}
-				m.certificateAuthorities = append(m.certificateAuthorities, ca)
-			}
-		default:
-			// Ignore unknown extensions.
-			continue
-		}
-
-		if !extData.Empty() {
-			return false
-		}
-	}
-
-	return true
-}
-
-type certificateMsg struct {
-	raw          []byte
-	certificates [][]byte
-}
-
-func (m *certificateMsg) marshal() (x []byte) {
-	if m.raw != nil {
-		return m.raw
-	}
-
-	var i int
-	for _, slice := range m.certificates {
-		i += len(slice)
-	}
-
-	length := 3 + 3*len(m.certificates) + i
-	x = make([]byte, 4+length)
-	x[0] = typeCertificate
-	x[1] = uint8(length >> 16)
-	x[2] = uint8(length >> 8)
-	x[3] = uint8(length)
-
-	certificateOctets := length - 3
-	x[4] = uint8(certificateOctets >> 16)
-	x[5] = uint8(certificateOctets >> 8)
-	x[6] = uint8(certificateOctets)
-
-	y := x[7:]
-	for _, slice := range m.certificates {
-		y[0] = uint8(len(slice) >> 16)
-		y[1] = uint8(len(slice) >> 8)
-		y[2] = uint8(len(slice))
-		copy(y[3:], slice)
-		y = y[3+len(slice):]
-	}
-
-	m.raw = x
-	return
-}
-
-func (m *certificateMsg) unmarshal(data []byte) bool {
-	if len(data) < 7 {
-		return false
-	}
-
-	m.raw = data
-	certsLen := uint32(data[4])<<16 | uint32(data[5])<<8 | uint32(data[6])
-	if uint32(len(data)) != certsLen+7 {
-		return false
-	}
-
-	numCerts := 0
-	d := data[7:]
-	for certsLen > 0 {
-		if len(d) < 4 {
-			return false
-		}
-		certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2])
-		if uint32(len(d)) < 3+certLen {
-			return false
-		}
-		d = d[3+certLen:]
-		certsLen -= 3 + certLen
-		numCerts++
-	}
-
-	m.certificates = make([][]byte, numCerts)
-	d = data[7:]
-	for i := 0; i < numCerts; i++ {
-		certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2])
-		m.certificates[i] = d[3 : 3+certLen]
-		d = d[3+certLen:]
-	}
-
-	return true
-}
-
-type certificateMsgTLS13 struct {
-	raw                 []byte
-	certificate         Certificate
-	ocspStapling        bool
-	scts                bool
-	delegatedCredential bool
-}
-
-func (m *certificateMsgTLS13) marshal() []byte {
-	if m.raw != nil {
-		return m.raw
-	}
-
-	var b cryptobyte.Builder
-	b.AddUint8(typeCertificate)
-	b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
-		b.AddUint8(0) // certificate_request_context
-
-		certificate := m.certificate
-		if !m.ocspStapling {
-			certificate.OCSPStaple = nil
-		}
-		if !m.scts {
-			certificate.SignedCertificateTimestamps = nil
-		}
-		if !m.delegatedCredential {
-			certificate.DelegatedCredential = nil
-		}
-		marshalCertificate(b, certificate)
-	})
-
-	m.raw = b.BytesOrPanic()
-
-	return m.raw
-}
-
-func marshalCertificate(b *cryptobyte.Builder, certificate Certificate) {
-	b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
-		for i, cert := range certificate.Certificate {
-			b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
-				b.AddBytes(cert)
-			})
-			b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-				if i > 0 {
-					// This library only supports OCSP, SCT and Delegated Credentials for leaf certificates.
-					// Delegated Credentials are only supported on the leaf/end-entity certificate.
-					return
-				}
-				if certificate.OCSPStaple != nil {
-					b.AddUint16(extensionStatusRequest)
-					b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-						b.AddUint8(statusTypeOCSP)
-						b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
-							b.AddBytes(certificate.OCSPStaple)
-						})
-					})
-				}
-				if certificate.SignedCertificateTimestamps != nil {
-					b.AddUint16(extensionSCT)
-					b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-						b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-							for _, sct := range certificate.SignedCertificateTimestamps {
-								b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-									b.AddBytes(sct)
-								})
-							}
-						})
-					})
-				}
-				if certificate.DelegatedCredential != nil {
-					b.AddUint16(extensionDelegatedCredentials)
-					b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-						b.AddBytes(certificate.DelegatedCredential)
-					})
-				}
-			})
-		}
-	})
-}
-
-func (m *certificateMsgTLS13) unmarshal(data []byte) bool {
-	*m = certificateMsgTLS13{raw: data}
-	s := cryptobyte.String(data)
-
-	var context cryptobyte.String
-	if !s.Skip(4) || // message type and uint24 length field
-		!s.ReadUint8LengthPrefixed(&context) || !context.Empty() ||
-		!unmarshalCertificate(&s, &m.certificate) ||
-		!s.Empty() {
-		return false
-	}
-
-	m.scts = m.certificate.SignedCertificateTimestamps != nil
-	m.ocspStapling = m.certificate.OCSPStaple != nil
-	m.delegatedCredential = m.certificate.DelegatedCredential != nil
-
-	return true
-}
-
-func unmarshalCertificate(s *cryptobyte.String, certificate *Certificate) bool {
-	var certList cryptobyte.String
-	if !s.ReadUint24LengthPrefixed(&certList) {
-		return false
-	}
-	for !certList.Empty() {
-		var cert []byte
-		var extensions cryptobyte.String
-		if !readUint24LengthPrefixed(&certList, &cert) ||
-			!certList.ReadUint16LengthPrefixed(&extensions) {
-			return false
-		}
-		certificate.Certificate = append(certificate.Certificate, cert)
-		for !extensions.Empty() {
-			var extension uint16
-			var extData cryptobyte.String
-			if !extensions.ReadUint16(&extension) ||
-				!extensions.ReadUint16LengthPrefixed(&extData) {
-				return false
-			}
-			if len(certificate.Certificate) > 1 {
-				// This library only supports OCSP and SCT for leaf certificates.
-				continue
-			}
-
-			switch extension {
-			case extensionStatusRequest:
-				var statusType uint8
-				if !extData.ReadUint8(&statusType) || statusType != statusTypeOCSP ||
-					!readUint24LengthPrefixed(&extData, &certificate.OCSPStaple) ||
-					len(certificate.OCSPStaple) == 0 {
-					return false
-				}
-			case extensionSCT:
-				var sctList cryptobyte.String
-				if !extData.ReadUint16LengthPrefixed(&sctList) || sctList.Empty() {
-					return false
-				}
-				for !sctList.Empty() {
-					var sct []byte
-					if !readUint16LengthPrefixed(&sctList, &sct) ||
-						len(sct) == 0 {
-						return false
-					}
-					certificate.SignedCertificateTimestamps = append(
-						certificate.SignedCertificateTimestamps, sct)
-				}
-			case extensionDelegatedCredentials:
-				if !extData.ReadBytes(&certificate.DelegatedCredential, len(extData)) {
-					return false
-				}
-				if len(certificate.DelegatedCredential) == 0 {
-					return false
-				}
-			default:
-				// Ignore unknown extensions.
-				continue
-			}
-
-			if !extData.Empty() {
-				return false
-			}
-		}
-	}
-	return true
-}
-
-type serverKeyExchangeMsg struct {
-	raw []byte
-	key []byte
-}
-
-func (m *serverKeyExchangeMsg) marshal() []byte {
-	if m.raw != nil {
-		return m.raw
-	}
-	length := len(m.key)
-	x := make([]byte, length+4)
-	x[0] = typeServerKeyExchange
-	x[1] = uint8(length >> 16)
-	x[2] = uint8(length >> 8)
-	x[3] = uint8(length)
-	copy(x[4:], m.key)
-
-	m.raw = x
-	return x
-}
-
-func (m *serverKeyExchangeMsg) unmarshal(data []byte) bool {
-	m.raw = data
-	if len(data) < 4 {
-		return false
-	}
-	m.key = data[4:]
-	return true
-}
-
-type certificateStatusMsg struct {
-	raw      []byte
-	response []byte
-}
-
-func (m *certificateStatusMsg) marshal() []byte {
-	if m.raw != nil {
-		return m.raw
-	}
-
-	var b cryptobyte.Builder
-	b.AddUint8(typeCertificateStatus)
-	b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
-		b.AddUint8(statusTypeOCSP)
-		b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
-			b.AddBytes(m.response)
-		})
-	})
-
-	m.raw = b.BytesOrPanic()
-	return m.raw
-}
-
-func (m *certificateStatusMsg) unmarshal(data []byte) bool {
-	m.raw = data
-	s := cryptobyte.String(data)
-
-	var statusType uint8
-	if !s.Skip(4) || // message type and uint24 length field
-		!s.ReadUint8(&statusType) || statusType != statusTypeOCSP ||
-		!readUint24LengthPrefixed(&s, &m.response) ||
-		len(m.response) == 0 || !s.Empty() {
-		return false
-	}
-	return true
-}
-
-type serverHelloDoneMsg struct{}
-
-func (m *serverHelloDoneMsg) marshal() []byte {
-	x := make([]byte, 4)
-	x[0] = typeServerHelloDone
-	return x
-}
-
-func (m *serverHelloDoneMsg) unmarshal(data []byte) bool {
-	return len(data) == 4
-}
-
-type clientKeyExchangeMsg struct {
-	raw        []byte
-	ciphertext []byte
-}
-
-func (m *clientKeyExchangeMsg) marshal() []byte {
-	if m.raw != nil {
-		return m.raw
-	}
-	length := len(m.ciphertext)
-	x := make([]byte, length+4)
-	x[0] = typeClientKeyExchange
-	x[1] = uint8(length >> 16)
-	x[2] = uint8(length >> 8)
-	x[3] = uint8(length)
-	copy(x[4:], m.ciphertext)
-
-	m.raw = x
-	return x
-}
-
-func (m *clientKeyExchangeMsg) unmarshal(data []byte) bool {
-	m.raw = data
-	if len(data) < 4 {
-		return false
-	}
-	l := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
-	if l != len(data)-4 {
-		return false
-	}
-	m.ciphertext = data[4:]
-	return true
-}
-
-type finishedMsg struct {
-	raw        []byte
-	verifyData []byte
-}
-
-func (m *finishedMsg) marshal() []byte {
-	if m.raw != nil {
-		return m.raw
-	}
-
-	var b cryptobyte.Builder
-	b.AddUint8(typeFinished)
-	b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
-		b.AddBytes(m.verifyData)
-	})
-
-	m.raw = b.BytesOrPanic()
-	return m.raw
-}
-
-func (m *finishedMsg) unmarshal(data []byte) bool {
-	m.raw = data
-	s := cryptobyte.String(data)
-	return s.Skip(1) &&
-		readUint24LengthPrefixed(&s, &m.verifyData) &&
-		s.Empty()
-}
-
-type certificateRequestMsg struct {
-	raw []byte
-	// hasSignatureAlgorithm indicates whether this message includes a list of
-	// supported signature algorithms. This change was introduced with TLS 1.2.
-	hasSignatureAlgorithm bool
-
-	certificateTypes             []byte
-	supportedSignatureAlgorithms []SignatureScheme
-	certificateAuthorities       [][]byte
-}
-
-func (m *certificateRequestMsg) marshal() (x []byte) {
-	if m.raw != nil {
-		return m.raw
-	}
-
-	// See RFC 4346, Section 7.4.4.
-	length := 1 + len(m.certificateTypes) + 2
-	casLength := 0
-	for _, ca := range m.certificateAuthorities {
-		casLength += 2 + len(ca)
-	}
-	length += casLength
-
-	if m.hasSignatureAlgorithm {
-		length += 2 + 2*len(m.supportedSignatureAlgorithms)
-	}
-
-	x = make([]byte, 4+length)
-	x[0] = typeCertificateRequest
-	x[1] = uint8(length >> 16)
-	x[2] = uint8(length >> 8)
-	x[3] = uint8(length)
-
-	x[4] = uint8(len(m.certificateTypes))
-
-	copy(x[5:], m.certificateTypes)
-	y := x[5+len(m.certificateTypes):]
-
-	if m.hasSignatureAlgorithm {
-		n := len(m.supportedSignatureAlgorithms) * 2
-		y[0] = uint8(n >> 8)
-		y[1] = uint8(n)
-		y = y[2:]
-		for _, sigAlgo := range m.supportedSignatureAlgorithms {
-			y[0] = uint8(sigAlgo >> 8)
-			y[1] = uint8(sigAlgo)
-			y = y[2:]
-		}
-	}
-
-	y[0] = uint8(casLength >> 8)
-	y[1] = uint8(casLength)
-	y = y[2:]
-	for _, ca := range m.certificateAuthorities {
-		y[0] = uint8(len(ca) >> 8)
-		y[1] = uint8(len(ca))
-		y = y[2:]
-		copy(y, ca)
-		y = y[len(ca):]
-	}
-
-	m.raw = x
-	return
-}
-
-func (m *certificateRequestMsg) unmarshal(data []byte) bool {
-	m.raw = data
-
-	if len(data) < 5 {
-		return false
-	}
-
-	length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
-	if uint32(len(data))-4 != length {
-		return false
-	}
-
-	numCertTypes := int(data[4])
-	data = data[5:]
-	if numCertTypes == 0 || len(data) <= numCertTypes {
-		return false
-	}
-
-	m.certificateTypes = make([]byte, numCertTypes)
-	if copy(m.certificateTypes, data) != numCertTypes {
-		return false
-	}
-
-	data = data[numCertTypes:]
-
-	if m.hasSignatureAlgorithm {
-		if len(data) < 2 {
-			return false
-		}
-		sigAndHashLen := uint16(data[0])<<8 | uint16(data[1])
-		data = data[2:]
-		if sigAndHashLen&1 != 0 {
-			return false
-		}
-		if len(data) < int(sigAndHashLen) {
-			return false
-		}
-		numSigAlgos := sigAndHashLen / 2
-		m.supportedSignatureAlgorithms = make([]SignatureScheme, numSigAlgos)
-		for i := range m.supportedSignatureAlgorithms {
-			m.supportedSignatureAlgorithms[i] = SignatureScheme(data[0])<<8 | SignatureScheme(data[1])
-			data = data[2:]
-		}
-	}
-
-	if len(data) < 2 {
-		return false
-	}
-	casLength := uint16(data[0])<<8 | uint16(data[1])
-	data = data[2:]
-	if len(data) < int(casLength) {
-		return false
-	}
-	cas := make([]byte, casLength)
-	copy(cas, data)
-	data = data[casLength:]
-
-	m.certificateAuthorities = nil
-	for len(cas) > 0 {
-		if len(cas) < 2 {
-			return false
-		}
-		caLen := uint16(cas[0])<<8 | uint16(cas[1])
-		cas = cas[2:]
-
-		if len(cas) < int(caLen) {
-			return false
-		}
-
-		m.certificateAuthorities = append(m.certificateAuthorities, cas[:caLen])
-		cas = cas[caLen:]
-	}
-
-	return len(data) == 0
-}
-
-type certificateVerifyMsg struct {
-	raw                   []byte
-	hasSignatureAlgorithm bool // format change introduced in TLS 1.2
-	signatureAlgorithm    SignatureScheme
-	signature             []byte
-}
-
-func (m *certificateVerifyMsg) marshal() (x []byte) {
-	if m.raw != nil {
-		return m.raw
-	}
-
-	var b cryptobyte.Builder
-	b.AddUint8(typeCertificateVerify)
-	b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
-		if m.hasSignatureAlgorithm {
-			b.AddUint16(uint16(m.signatureAlgorithm))
-		}
-		b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-			b.AddBytes(m.signature)
-		})
-	})
-
-	m.raw = b.BytesOrPanic()
-	return m.raw
-}
-
-func (m *certificateVerifyMsg) unmarshal(data []byte) bool {
-	m.raw = data
-	s := cryptobyte.String(data)
-
-	if !s.Skip(4) { // message type and uint24 length field
-		return false
-	}
-	if m.hasSignatureAlgorithm {
-		if !s.ReadUint16((*uint16)(&m.signatureAlgorithm)) {
-			return false
-		}
-	}
-	return readUint16LengthPrefixed(&s, &m.signature) && s.Empty()
-}
-
-type newSessionTicketMsg struct {
-	raw    []byte
-	ticket []byte
-}
-
-func (m *newSessionTicketMsg) marshal() (x []byte) {
-	if m.raw != nil {
-		return m.raw
-	}
-
-	// See RFC 5077, Section 3.3.
-	ticketLen := len(m.ticket)
-	length := 2 + 4 + ticketLen
-	x = make([]byte, 4+length)
-	x[0] = typeNewSessionTicket
-	x[1] = uint8(length >> 16)
-	x[2] = uint8(length >> 8)
-	x[3] = uint8(length)
-	x[8] = uint8(ticketLen >> 8)
-	x[9] = uint8(ticketLen)
-	copy(x[10:], m.ticket)
-
-	m.raw = x
-
-	return
-}
-
-func (m *newSessionTicketMsg) unmarshal(data []byte) bool {
-	m.raw = data
-
-	if len(data) < 10 {
-		return false
-	}
-
-	length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
-	if uint32(len(data))-4 != length {
-		return false
-	}
-
-	ticketLen := int(data[8])<<8 + int(data[9])
-	if len(data)-10 != ticketLen {
-		return false
-	}
-
-	m.ticket = data[10:]
-
-	return true
-}
-
-type helloRequestMsg struct{}
-
-func (*helloRequestMsg) marshal() []byte {
-	return []byte{typeHelloRequest, 0, 0, 0}
-}
-
-func (*helloRequestMsg) unmarshal(data []byte) bool {
-	return len(data) == 4
-}

+ 0 - 893
transport/cloudflaretls/handshake_server.go

@@ -1,893 +0,0 @@
-// Copyright 2009 The Go Authors. 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 (
-	"context"
-	"crypto"
-	"crypto/ecdsa"
-	"crypto/ed25519"
-	"crypto/rsa"
-	"crypto/subtle"
-	"crypto/x509"
-	"errors"
-	"fmt"
-	"hash"
-	"io"
-	"sync/atomic"
-	"time"
-
-	circlSign "github.com/cloudflare/circl/sign"
-)
-
-// serverHandshakeState contains details of a server handshake in progress.
-// It's discarded once the handshake has completed.
-type serverHandshakeState struct {
-	c            *Conn
-	ctx          context.Context
-	clientHello  *clientHelloMsg
-	hello        *serverHelloMsg
-	suite        *cipherSuite
-	ecdheOk      bool
-	ecSignOk     bool
-	rsaDecryptOk bool
-	rsaSignOk    bool
-	sessionState *sessionState
-	finishedHash finishedHash
-	masterSecret []byte
-	cert         *Certificate
-}
-
-// serverHandshake performs a TLS handshake as a server.
-func (c *Conn) serverHandshake(ctx context.Context) error {
-	clientHello, err := c.readClientHello(ctx)
-	if err != nil {
-		return err
-	}
-
-	if c.vers == VersionTLS13 {
-		hs := serverHandshakeStateTLS13{
-			c:           c,
-			ctx:         ctx,
-			clientHello: clientHello,
-			hsTimings:   createTLS13ServerHandshakeTimingInfo(c.config.Time),
-		}
-		return hs.handshake()
-	}
-
-	hs := serverHandshakeState{
-		c:           c,
-		ctx:         ctx,
-		clientHello: clientHello,
-	}
-	return hs.handshake()
-}
-
-func (hs *serverHandshakeState) handshake() error {
-	c := hs.c
-
-	if err := hs.processClientHello(); err != nil {
-		return err
-	}
-
-	// For an overview of TLS handshaking, see RFC 5246, Section 7.3.
-	c.buffering = true
-	if hs.checkForResumption() {
-		// The client has included a session ticket and so we do an abbreviated handshake.
-		c.didResume = true
-		if err := hs.doResumeHandshake(); err != nil {
-			return err
-		}
-		if err := hs.establishKeys(); err != nil {
-			return err
-		}
-		if err := hs.sendSessionTicket(); err != nil {
-			return err
-		}
-		if err := hs.sendFinished(c.serverFinished[:]); err != nil {
-			return err
-		}
-		if _, err := c.flush(); err != nil {
-			return err
-		}
-		c.clientFinishedIsFirst = false
-		if err := hs.readFinished(nil); err != nil {
-			return err
-		}
-	} else {
-		// The client didn't include a session ticket, or it wasn't
-		// valid so we do a full handshake.
-		if err := hs.pickCipherSuite(); err != nil {
-			return err
-		}
-		if err := hs.doFullHandshake(); err != nil {
-			return err
-		}
-		if err := hs.establishKeys(); err != nil {
-			return err
-		}
-		if err := hs.readFinished(c.clientFinished[:]); err != nil {
-			return err
-		}
-		c.clientFinishedIsFirst = true
-		c.buffering = true
-		if err := hs.sendSessionTicket(); err != nil {
-			return err
-		}
-		if err := hs.sendFinished(nil); err != nil {
-			return err
-		}
-		if _, err := c.flush(); err != nil {
-			return err
-		}
-	}
-
-	c.ekm = ekmFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.clientHello.random, hs.hello.random)
-	atomic.StoreUint32(&c.handshakeStatus, 1)
-
-	return nil
-}
-
-// readClientHello reads a ClientHello message and selects the protocol version.
-func (c *Conn) readClientHello(ctx context.Context) (*clientHelloMsg, error) {
-	msg, err := c.readHandshake()
-	if err != nil {
-		return nil, err
-	}
-	clientHello, ok := msg.(*clientHelloMsg)
-	if !ok {
-		c.sendAlert(alertUnexpectedMessage)
-		return nil, unexpectedMessageError(clientHello, msg)
-	}
-
-	// NOTE(cjpatton): ECH usage is resolved before calling GetConfigForClient()
-	// or GetCertifciate(). Hence, it is not currently possible to reject ECH if
-	// we don't recognize the inner SNI. This may or may not be desirable in the
-	// future.
-	clientHello, err = c.echAcceptOrReject(clientHello, false) // afterHRR == false
-	if err != nil {
-		return nil, fmt.Errorf("tls: %s", err) // Alert sent.
-	}
-
-	var configForClient *Config
-	originalConfig := c.config
-	if c.config.GetConfigForClient != nil {
-		chi := clientHelloInfo(ctx, c, clientHello)
-		if configForClient, err = c.config.GetConfigForClient(chi); err != nil {
-			c.sendAlert(alertInternalError)
-			return nil, err
-		} else if configForClient != nil {
-			c.config = configForClient
-		}
-	}
-	c.ticketKeys = originalConfig.ticketKeys(configForClient)
-
-	clientVersions := clientHello.supportedVersions
-	if len(clientHello.supportedVersions) == 0 {
-		clientVersions = supportedVersionsFromMax(clientHello.vers)
-	}
-	c.vers, ok = c.config.mutualVersion(roleServer, clientVersions)
-	if !ok {
-		c.sendAlert(alertProtocolVersion)
-		return nil, fmt.Errorf("tls: client offered only unsupported versions: %x", clientVersions)
-	}
-	c.haveVers = true
-	c.in.version = c.vers
-	c.out.version = c.vers
-
-	return clientHello, nil
-}
-
-func (hs *serverHandshakeState) processClientHello() error {
-	c := hs.c
-
-	hs.hello = new(serverHelloMsg)
-	hs.hello.vers = c.vers
-
-	foundCompression := false
-	// We only support null compression, so check that the client offered it.
-	for _, compression := range hs.clientHello.compressionMethods {
-		if compression == compressionNone {
-			foundCompression = true
-			break
-		}
-	}
-
-	if !foundCompression {
-		c.sendAlert(alertHandshakeFailure)
-		return errors.New("tls: client does not support uncompressed connections")
-	}
-
-	hs.hello.random = make([]byte, 32)
-	serverRandom := hs.hello.random
-	// Downgrade protection canaries. See RFC 8446, Section 4.1.3.
-	maxVers := c.config.maxSupportedVersion(roleServer)
-	if maxVers >= VersionTLS12 && c.vers < maxVers || testingOnlyForceDowngradeCanary {
-		if c.vers == VersionTLS12 {
-			copy(serverRandom[24:], downgradeCanaryTLS12)
-		} else {
-			copy(serverRandom[24:], downgradeCanaryTLS11)
-		}
-		serverRandom = serverRandom[:24]
-	}
-	_, err := io.ReadFull(c.config.rand(), serverRandom)
-	if err != nil {
-		c.sendAlert(alertInternalError)
-		return err
-	}
-
-	if len(hs.clientHello.secureRenegotiation) != 0 {
-		c.sendAlert(alertHandshakeFailure)
-		return errors.New("tls: initial handshake had non-empty renegotiation extension")
-	}
-
-	hs.hello.secureRenegotiationSupported = hs.clientHello.secureRenegotiationSupported
-	hs.hello.compressionMethod = compressionNone
-	if len(hs.clientHello.serverName) > 0 {
-		c.serverName = hs.clientHello.serverName
-	}
-
-	selectedProto, err := negotiateALPN(c.config.NextProtos, hs.clientHello.alpnProtocols)
-	if err != nil {
-		c.sendAlert(alertNoApplicationProtocol)
-		return err
-	}
-	hs.hello.alpnProtocol = selectedProto
-	c.clientProtocol = selectedProto
-
-	hs.cert, err = c.config.getCertificate(clientHelloInfo(hs.ctx, c, hs.clientHello))
-	if err != nil {
-		if err == errNoCertificates {
-			c.sendAlert(alertUnrecognizedName)
-		} else {
-			c.sendAlert(alertInternalError)
-		}
-		return err
-	}
-	if hs.clientHello.scts {
-		hs.hello.scts = hs.cert.SignedCertificateTimestamps
-	}
-
-	hs.ecdheOk = supportsECDHE(c.config, hs.clientHello.supportedCurves, hs.clientHello.supportedPoints)
-
-	if hs.ecdheOk {
-		// Although omitting the ec_point_formats extension is permitted, some
-		// old OpenSSL version will refuse to handshake if not present.
-		//
-		// Per RFC 4492, section 5.1.2, implementations MUST support the
-		// uncompressed point format. See golang.org/issue/31943.
-		hs.hello.supportedPoints = []uint8{pointFormatUncompressed}
-	}
-
-	if priv, ok := hs.cert.PrivateKey.(crypto.Signer); ok {
-		switch priv.Public().(type) {
-		case *ecdsa.PublicKey:
-			hs.ecSignOk = true
-		case ed25519.PublicKey:
-			hs.ecSignOk = true
-		case *rsa.PublicKey:
-			hs.rsaSignOk = true
-		default:
-			c.sendAlert(alertInternalError)
-			return fmt.Errorf("tls: unsupported signing key type (%T)", priv.Public())
-		}
-	}
-	if priv, ok := hs.cert.PrivateKey.(crypto.Decrypter); ok {
-		switch priv.Public().(type) {
-		case *rsa.PublicKey:
-			hs.rsaDecryptOk = true
-		default:
-			c.sendAlert(alertInternalError)
-			return fmt.Errorf("tls: unsupported decryption key type (%T)", priv.Public())
-		}
-	}
-
-	return nil
-}
-
-// negotiateALPN picks a shared ALPN protocol that both sides support in server
-// preference order. If ALPN is not configured or the peer doesn't support it,
-// it returns "" and no error.
-func negotiateALPN(serverProtos, clientProtos []string) (string, error) {
-	if len(serverProtos) == 0 || len(clientProtos) == 0 {
-		return "", nil
-	}
-	var http11fallback bool
-	for _, s := range serverProtos {
-		for _, c := range clientProtos {
-			if s == c {
-				return s, nil
-			}
-			if s == "h2" && c == "http/1.1" {
-				http11fallback = true
-			}
-		}
-	}
-	// As a special case, let http/1.1 clients connect to h2 servers as if they
-	// didn't support ALPN. We used not to enforce protocol overlap, so over
-	// time a number of HTTP servers were configured with only "h2", but
-	// expected to accept connections from "http/1.1" clients. See Issue 46310.
-	if http11fallback {
-		return "", nil
-	}
-	return "", fmt.Errorf("tls: client requested unsupported application protocols (%s)", clientProtos)
-}
-
-// supportsECDHE returns whether ECDHE key exchanges can be used with this
-// pre-TLS 1.3 client.
-func supportsECDHE(c *Config, supportedCurves []CurveID, supportedPoints []uint8) bool {
-	supportsCurve := false
-	for _, curve := range supportedCurves {
-		if c.supportsCurve(curve) {
-			supportsCurve = true
-			break
-		}
-	}
-
-	supportsPointFormat := false
-	for _, pointFormat := range supportedPoints {
-		if pointFormat == pointFormatUncompressed {
-			supportsPointFormat = true
-			break
-		}
-	}
-
-	return supportsCurve && supportsPointFormat
-}
-
-func (hs *serverHandshakeState) pickCipherSuite() error {
-	c := hs.c
-
-	preferenceOrder := cipherSuitesPreferenceOrder
-	if !hasAESGCMHardwareSupport || !aesgcmPreferred(hs.clientHello.cipherSuites) {
-		preferenceOrder = cipherSuitesPreferenceOrderNoAES
-	}
-
-	configCipherSuites := c.config.cipherSuites()
-	preferenceList := make([]uint16, 0, len(configCipherSuites))
-	for _, suiteID := range preferenceOrder {
-		for _, id := range configCipherSuites {
-			if id == suiteID {
-				preferenceList = append(preferenceList, id)
-				break
-			}
-		}
-	}
-
-	hs.suite = selectCipherSuite(preferenceList, hs.clientHello.cipherSuites, hs.cipherSuiteOk)
-	if hs.suite == nil {
-		c.sendAlert(alertHandshakeFailure)
-		return errors.New("tls: no cipher suite supported by both client and server")
-	}
-	c.cipherSuite = hs.suite.id
-
-	for _, id := range hs.clientHello.cipherSuites {
-		if id == TLS_FALLBACK_SCSV {
-			// The client is doing a fallback connection. See RFC 7507.
-			if hs.clientHello.vers < c.config.maxSupportedVersion(roleServer) {
-				c.sendAlert(alertInappropriateFallback)
-				return errors.New("tls: client using inappropriate protocol fallback")
-			}
-			break
-		}
-	}
-
-	return nil
-}
-
-func (hs *serverHandshakeState) cipherSuiteOk(c *cipherSuite) bool {
-	if c.flags&suiteECDHE != 0 {
-		if !hs.ecdheOk {
-			return false
-		}
-		if c.flags&suiteECSign != 0 {
-			if !hs.ecSignOk {
-				return false
-			}
-		} else if !hs.rsaSignOk {
-			return false
-		}
-	} else if !hs.rsaDecryptOk {
-		return false
-	}
-	if hs.c.vers < VersionTLS12 && c.flags&suiteTLS12 != 0 {
-		return false
-	}
-	return true
-}
-
-// checkForResumption reports whether we should perform resumption on this connection.
-func (hs *serverHandshakeState) checkForResumption() bool {
-	c := hs.c
-
-	if c.config.SessionTicketsDisabled || c.config.ECHEnabled {
-		return false
-	}
-
-	plaintext, usedOldKey := c.decryptTicket(hs.clientHello.sessionTicket)
-	if plaintext == nil {
-		return false
-	}
-	hs.sessionState = &sessionState{usedOldKey: usedOldKey}
-	ok := hs.sessionState.unmarshal(plaintext)
-	if !ok {
-		return false
-	}
-
-	createdAt := time.Unix(int64(hs.sessionState.createdAt), 0)
-	if c.config.time().Sub(createdAt) > maxSessionTicketLifetime {
-		return false
-	}
-
-	// Never resume a session for a different TLS version.
-	if c.vers != hs.sessionState.vers {
-		return false
-	}
-
-	cipherSuiteOk := false
-	// Check that the client is still offering the ciphersuite in the session.
-	for _, id := range hs.clientHello.cipherSuites {
-		if id == hs.sessionState.cipherSuite {
-			cipherSuiteOk = true
-			break
-		}
-	}
-	if !cipherSuiteOk {
-		return false
-	}
-
-	// Check that we also support the ciphersuite from the session.
-	hs.suite = selectCipherSuite([]uint16{hs.sessionState.cipherSuite},
-		c.config.cipherSuites(), hs.cipherSuiteOk)
-	if hs.suite == nil {
-		return false
-	}
-
-	sessionHasClientCerts := len(hs.sessionState.certificates) != 0
-	needClientCerts := requiresClientCert(c.config.ClientAuth)
-	if needClientCerts && !sessionHasClientCerts {
-		return false
-	}
-	if sessionHasClientCerts && c.config.ClientAuth == NoClientCert {
-		return false
-	}
-
-	return true
-}
-
-func (hs *serverHandshakeState) doResumeHandshake() error {
-	c := hs.c
-
-	hs.hello.cipherSuite = hs.suite.id
-	c.cipherSuite = hs.suite.id
-	// We echo the client's session ID in the ServerHello to let it know
-	// that we're doing a resumption.
-	hs.hello.sessionId = hs.clientHello.sessionId
-	hs.hello.ticketSupported = hs.sessionState.usedOldKey
-	hs.finishedHash = newFinishedHash(c.vers, hs.suite)
-	hs.finishedHash.discardHandshakeBuffer()
-	hs.finishedHash.Write(hs.clientHello.marshal())
-	hs.finishedHash.Write(hs.hello.marshal())
-	if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil {
-		return err
-	}
-
-	if err := c.processCertsFromClient(Certificate{
-		Certificate: hs.sessionState.certificates,
-	}); err != nil {
-		return err
-	}
-
-	if c.config.VerifyConnection != nil {
-		if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil {
-			c.sendAlert(alertBadCertificate)
-			return err
-		}
-	}
-
-	hs.masterSecret = hs.sessionState.masterSecret
-
-	return nil
-}
-
-func (hs *serverHandshakeState) doFullHandshake() error {
-	c := hs.c
-
-	if hs.clientHello.ocspStapling && len(hs.cert.OCSPStaple) > 0 {
-		hs.hello.ocspStapling = true
-	}
-
-	hs.hello.ticketSupported = hs.clientHello.ticketSupported && !c.config.SessionTicketsDisabled && !c.config.ECHEnabled
-	hs.hello.cipherSuite = hs.suite.id
-
-	hs.finishedHash = newFinishedHash(hs.c.vers, hs.suite)
-	if c.config.ClientAuth == NoClientCert {
-		// No need to keep a full record of the handshake if client
-		// certificates won't be used.
-		hs.finishedHash.discardHandshakeBuffer()
-	}
-	hs.finishedHash.Write(hs.clientHello.marshal())
-	hs.finishedHash.Write(hs.hello.marshal())
-	if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil {
-		return err
-	}
-
-	certMsg := new(certificateMsg)
-	certMsg.certificates = hs.cert.Certificate
-	hs.finishedHash.Write(certMsg.marshal())
-	if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil {
-		return err
-	}
-
-	if hs.hello.ocspStapling {
-		certStatus := new(certificateStatusMsg)
-		certStatus.response = hs.cert.OCSPStaple
-		hs.finishedHash.Write(certStatus.marshal())
-		if _, err := c.writeRecord(recordTypeHandshake, certStatus.marshal()); err != nil {
-			return err
-		}
-	}
-
-	keyAgreement := hs.suite.ka(c.vers)
-	skx, err := keyAgreement.generateServerKeyExchange(c.config, hs.cert, hs.clientHello, hs.hello)
-	if err != nil {
-		c.sendAlert(alertHandshakeFailure)
-		return err
-	}
-	if skx != nil {
-		hs.finishedHash.Write(skx.marshal())
-		if _, err := c.writeRecord(recordTypeHandshake, skx.marshal()); err != nil {
-			return err
-		}
-	}
-
-	var certReq *certificateRequestMsg
-	if c.config.ClientAuth >= RequestClientCert {
-		// Request a client certificate
-		certReq = new(certificateRequestMsg)
-		certReq.certificateTypes = []byte{
-			byte(certTypeRSASign),
-			byte(certTypeECDSASign),
-		}
-		if c.vers >= VersionTLS12 {
-			certReq.hasSignatureAlgorithm = true
-			certReq.supportedSignatureAlgorithms = c.config.supportedSignatureAlgorithms()
-		}
-
-		// An empty list of certificateAuthorities signals to
-		// the client that it may send any certificate in response
-		// to our request. When we know the CAs we trust, then
-		// we can send them down, so that the client can choose
-		// an appropriate certificate to give to us.
-		if c.config.ClientCAs != nil {
-			certReq.certificateAuthorities = c.config.ClientCAs.Subjects()
-		}
-		hs.finishedHash.Write(certReq.marshal())
-		if _, err := c.writeRecord(recordTypeHandshake, certReq.marshal()); err != nil {
-			return err
-		}
-	}
-
-	helloDone := new(serverHelloDoneMsg)
-	hs.finishedHash.Write(helloDone.marshal())
-	if _, err := c.writeRecord(recordTypeHandshake, helloDone.marshal()); err != nil {
-		return err
-	}
-
-	if _, err := c.flush(); err != nil {
-		return err
-	}
-
-	var pub crypto.PublicKey // public key for client auth, if any
-
-	msg, err := c.readHandshake()
-	if err != nil {
-		return err
-	}
-
-	// If we requested a client certificate, then the client must send a
-	// certificate message, even if it's empty.
-	if c.config.ClientAuth >= RequestClientCert {
-		certMsg, ok := msg.(*certificateMsg)
-		if !ok {
-			c.sendAlert(alertUnexpectedMessage)
-			return unexpectedMessageError(certMsg, msg)
-		}
-		hs.finishedHash.Write(certMsg.marshal())
-
-		if err := c.processCertsFromClient(Certificate{
-			Certificate: certMsg.certificates,
-		}); err != nil {
-			return err
-		}
-		if len(certMsg.certificates) != 0 {
-			pub = c.peerCertificates[0].PublicKey
-		}
-
-		msg, err = c.readHandshake()
-		if err != nil {
-			return err
-		}
-	}
-	if c.config.VerifyConnection != nil {
-		if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil {
-			c.sendAlert(alertBadCertificate)
-			return err
-		}
-	}
-
-	// Get client key exchange
-	ckx, ok := msg.(*clientKeyExchangeMsg)
-	if !ok {
-		c.sendAlert(alertUnexpectedMessage)
-		return unexpectedMessageError(ckx, msg)
-	}
-	hs.finishedHash.Write(ckx.marshal())
-
-	preMasterSecret, err := keyAgreement.processClientKeyExchange(c.config, hs.cert, ckx, c.vers)
-	if err != nil {
-		c.sendAlert(alertHandshakeFailure)
-		return err
-	}
-	if eccKex, ok := keyAgreement.(*ecdheKeyAgreement); ok {
-		c.handleCFEvent(CFEventTLSNegotiatedNamedKEX{
-			KEX: eccKex.params.CurveID(),
-		})
-	}
-	hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.clientHello.random, hs.hello.random)
-	if err := c.config.writeKeyLog(keyLogLabelTLS12, hs.clientHello.random, hs.masterSecret); err != nil {
-		c.sendAlert(alertInternalError)
-		return err
-	}
-
-	// If we received a client cert in response to our certificate request message,
-	// the client will send us a certificateVerifyMsg immediately after the
-	// clientKeyExchangeMsg. This message is a digest of all preceding
-	// handshake-layer messages that is signed using the private key corresponding
-	// to the client's certificate. This allows us to verify that the client is in
-	// possession of the private key of the certificate.
-	if len(c.peerCertificates) > 0 {
-		msg, err = c.readHandshake()
-		if err != nil {
-			return err
-		}
-		certVerify, ok := msg.(*certificateVerifyMsg)
-		if !ok {
-			c.sendAlert(alertUnexpectedMessage)
-			return unexpectedMessageError(certVerify, msg)
-		}
-
-		var sigType uint8
-		var sigHash crypto.Hash
-		if c.vers >= VersionTLS12 {
-			if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, certReq.supportedSignatureAlgorithms) {
-				c.sendAlert(alertIllegalParameter)
-				return errors.New("tls: client certificate used with invalid signature algorithm")
-			}
-			sigType, sigHash, err = typeAndHashFromSignatureScheme(certVerify.signatureAlgorithm)
-			if err != nil {
-				return c.sendAlert(alertInternalError)
-			}
-		} else {
-			sigType, sigHash, err = legacyTypeAndHashFromPublicKey(pub)
-			if err != nil {
-				c.sendAlert(alertIllegalParameter)
-				return err
-			}
-		}
-
-		signed := hs.finishedHash.hashForClientCertificate(sigType, sigHash, hs.masterSecret)
-		if err := verifyHandshakeSignature(sigType, pub, sigHash, signed, certVerify.signature); err != nil {
-			c.sendAlert(alertDecryptError)
-			return errors.New("tls: invalid signature by the client certificate: " + err.Error())
-		}
-
-		hs.finishedHash.Write(certVerify.marshal())
-	}
-
-	hs.finishedHash.discardHandshakeBuffer()
-
-	return nil
-}
-
-func (hs *serverHandshakeState) establishKeys() error {
-	c := hs.c
-
-	clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV := keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.clientHello.random, hs.hello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen)
-
-	var clientCipher, serverCipher any
-	var clientHash, serverHash hash.Hash
-
-	if hs.suite.aead == nil {
-		clientCipher = hs.suite.cipher(clientKey, clientIV, true /* for reading */)
-		clientHash = hs.suite.mac(clientMAC)
-		serverCipher = hs.suite.cipher(serverKey, serverIV, false /* not for reading */)
-		serverHash = hs.suite.mac(serverMAC)
-	} else {
-		clientCipher = hs.suite.aead(clientKey, clientIV)
-		serverCipher = hs.suite.aead(serverKey, serverIV)
-	}
-
-	c.in.prepareCipherSpec(c.vers, clientCipher, clientHash)
-	c.out.prepareCipherSpec(c.vers, serverCipher, serverHash)
-
-	return nil
-}
-
-func (hs *serverHandshakeState) readFinished(out []byte) error {
-	c := hs.c
-
-	if err := c.readChangeCipherSpec(); err != nil {
-		return err
-	}
-
-	msg, err := c.readHandshake()
-	if err != nil {
-		return err
-	}
-	clientFinished, ok := msg.(*finishedMsg)
-	if !ok {
-		c.sendAlert(alertUnexpectedMessage)
-		return unexpectedMessageError(clientFinished, msg)
-	}
-
-	verify := hs.finishedHash.clientSum(hs.masterSecret)
-	if len(verify) != len(clientFinished.verifyData) ||
-		subtle.ConstantTimeCompare(verify, clientFinished.verifyData) != 1 {
-		c.sendAlert(alertHandshakeFailure)
-		return errors.New("tls: client's Finished message is incorrect")
-	}
-
-	hs.finishedHash.Write(clientFinished.marshal())
-	copy(out, verify)
-	return nil
-}
-
-func (hs *serverHandshakeState) sendSessionTicket() error {
-	// ticketSupported is set in a resumption handshake if the
-	// ticket from the client was encrypted with an old session
-	// ticket key and thus a refreshed ticket should be sent.
-	if !hs.hello.ticketSupported {
-		return nil
-	}
-
-	c := hs.c
-	m := new(newSessionTicketMsg)
-
-	createdAt := uint64(c.config.time().Unix())
-	if hs.sessionState != nil {
-		// If this is re-wrapping an old key, then keep
-		// the original time it was created.
-		createdAt = hs.sessionState.createdAt
-	}
-
-	var certsFromClient [][]byte
-	for _, cert := range c.peerCertificates {
-		certsFromClient = append(certsFromClient, cert.Raw)
-	}
-	state := sessionState{
-		vers:         c.vers,
-		cipherSuite:  hs.suite.id,
-		createdAt:    createdAt,
-		masterSecret: hs.masterSecret,
-		certificates: certsFromClient,
-	}
-	var err error
-	m.ticket, err = c.encryptTicket(state.marshal())
-	if err != nil {
-		return err
-	}
-
-	hs.finishedHash.Write(m.marshal())
-	if _, err := c.writeRecord(recordTypeHandshake, m.marshal()); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func (hs *serverHandshakeState) sendFinished(out []byte) error {
-	c := hs.c
-
-	if _, err := c.writeRecord(recordTypeChangeCipherSpec, []byte{1}); err != nil {
-		return err
-	}
-
-	finished := new(finishedMsg)
-	finished.verifyData = hs.finishedHash.serverSum(hs.masterSecret)
-	hs.finishedHash.Write(finished.marshal())
-	if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil {
-		return err
-	}
-
-	copy(out, finished.verifyData)
-
-	return nil
-}
-
-// processCertsFromClient takes a chain of client certificates either from a
-// Certificates message or from a sessionState and verifies them. It returns
-// the public key of the leaf certificate.
-func (c *Conn) processCertsFromClient(certificate Certificate) error {
-	certificates := certificate.Certificate
-	certs := make([]*x509.Certificate, len(certificates))
-	var err error
-	for i, asn1Data := range certificates {
-		if certs[i], err = x509.ParseCertificate(asn1Data); err != nil {
-			c.sendAlert(alertBadCertificate)
-			return errors.New("tls: failed to parse client certificate: " + err.Error())
-		}
-	}
-
-	if len(certs) == 0 && requiresClientCert(c.config.ClientAuth) {
-		c.sendAlert(alertBadCertificate)
-		return errors.New("tls: client didn't provide a certificate")
-	}
-
-	if c.config.ClientAuth >= VerifyClientCertIfGiven && len(certs) > 0 {
-		opts := x509.VerifyOptions{
-			Roots:         c.config.ClientCAs,
-			CurrentTime:   c.config.time(),
-			Intermediates: x509.NewCertPool(),
-			KeyUsages:     []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
-		}
-
-		for _, cert := range certs[1:] {
-			opts.Intermediates.AddCert(cert)
-		}
-
-		chains, err := certs[0].Verify(opts)
-		if err != nil {
-			c.sendAlert(alertBadCertificate)
-			return errors.New("tls: failed to verify client certificate: " + err.Error())
-		}
-
-		c.verifiedChains = chains
-	}
-
-	c.peerCertificates = certs
-	c.ocspResponse = certificate.OCSPStaple
-	c.scts = certificate.SignedCertificateTimestamps
-
-	if len(certs) > 0 {
-		switch certs[0].PublicKey.(type) {
-		case *ecdsa.PublicKey, *rsa.PublicKey, ed25519.PublicKey, circlSign.PublicKey:
-		default:
-			c.sendAlert(alertUnsupportedCertificate)
-			return fmt.Errorf("tls: client certificate contains an unsupported public key of type %T", certs[0].PublicKey)
-		}
-	}
-
-	if c.config.VerifyPeerCertificate != nil {
-		if err := c.config.VerifyPeerCertificate(certificates, c.verifiedChains); err != nil {
-			c.sendAlert(alertBadCertificate)
-			return err
-		}
-	}
-
-	return nil
-}
-
-func clientHelloInfo(ctx context.Context, c *Conn, clientHello *clientHelloMsg) *ClientHelloInfo {
-	supportedVersions := clientHello.supportedVersions
-	if len(clientHello.supportedVersions) == 0 {
-		supportedVersions = supportedVersionsFromMax(clientHello.vers)
-	}
-
-	return &ClientHelloInfo{
-		CipherSuites:                clientHello.cipherSuites,
-		ServerName:                  clientHello.serverName,
-		SupportedCurves:             clientHello.supportedCurves,
-		SupportedPoints:             clientHello.supportedPoints,
-		SignatureSchemes:            clientHello.supportedSignatureAlgorithms,
-		SupportedProtos:             clientHello.alpnProtocols,
-		SupportedVersions:           supportedVersions,
-		SupportsDelegatedCredential: clientHello.delegatedCredentialSupported,
-		SignatureSchemesDC:          clientHello.supportedSignatureAlgorithmsDC,
-		Conn:                        c.conn,
-		config:                      c.config,
-		ctx:                         ctx,
-	}
-}

+ 0 - 1121
transport/cloudflaretls/handshake_server_tls13.go

@@ -1,1121 +0,0 @@
-// Copyright 2018 The Go Authors. 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 (
-	"bytes"
-	"context"
-	"crypto"
-	"crypto/hmac"
-	"crypto/rsa"
-	"encoding/binary"
-	"errors"
-	"fmt"
-	"hash"
-	"io"
-	"sync/atomic"
-	"time"
-)
-
-// maxClientPSKIdentities is the number of client PSK identities the server will
-// attempt to validate. It will ignore the rest not to let cheap ClientHello
-// messages cause too much work in session ticket decryption attempts.
-const maxClientPSKIdentities = 5
-
-type serverHandshakeStateTLS13 struct {
-	c               *Conn
-	ctx             context.Context
-	clientHello     *clientHelloMsg
-	hello           *serverHelloMsg
-	sentDummyCCS    bool
-	usingPSK        bool
-	suite           *cipherSuiteTLS13
-	cert            *Certificate
-	sigAlg          SignatureScheme
-	selectedGroup   CurveID
-	earlySecret     []byte
-	sharedKey       []byte
-	handshakeSecret []byte
-	masterSecret    []byte
-	trafficSecret   []byte // client_application_traffic_secret_0
-	transcript      hash.Hash
-	clientFinished  []byte
-	certReq         *certificateRequestMsgTLS13
-
-	hsTimings CFEventTLS13ServerHandshakeTimingInfo
-}
-
-func (hs *serverHandshakeStateTLS13) echIsInner() bool {
-	return len(hs.clientHello.ech) == 1 && hs.clientHello.ech[0] == echClientHelloInnerVariant
-}
-
-// processDelegatedCredentialFromClient unmarshals the DelegatedCredential
-// offered by the client (if present) and validates it using the peer's
-// certificate.
-func (hs *serverHandshakeStateTLS13) processDelegatedCredentialFromClient(rawDC []byte, certVerifyMsg *certificateVerifyMsg) error {
-	c := hs.c
-
-	var dc *DelegatedCredential
-	var err error
-	if rawDC != nil {
-		// Assert that the DC extension was indicated by the client.
-		if !hs.certReq.supportDelegatedCredential {
-			c.sendAlert(alertUnexpectedMessage)
-			return errors.New("tls: got Delegated Credential extension without indication")
-		}
-
-		dc, err = UnmarshalDelegatedCredential(rawDC)
-		if err != nil {
-			c.sendAlert(alertDecodeError)
-			return fmt.Errorf("tls: Delegated Credential: %s", err)
-		}
-
-		if !isSupportedSignatureAlgorithm(dc.cred.expCertVerfAlgo, supportedSignatureAlgorithmsDC) {
-			c.sendAlert(alertIllegalParameter)
-			return errors.New("tls: Delegated Credential used with invalid signature algorithm")
-		}
-	}
-
-	if dc != nil {
-		if !dc.Validate(c.peerCertificates[0], true, c.config.time(), certVerifyMsg) {
-			c.sendAlert(alertIllegalParameter)
-			return errors.New("tls: invalid Delegated Credential")
-		}
-	}
-
-	c.verifiedDC = dc
-
-	return nil
-}
-
-func (hs *serverHandshakeStateTLS13) handshake() error {
-	c := hs.c
-
-	// For an overview of the TLS 1.3 handshake, see RFC 8446, Section 2.
-	if err := hs.processClientHello(); err != nil {
-		return err
-	}
-	if err := hs.checkForResumption(); err != nil {
-		return err
-	}
-	if err := hs.pickCertificate(); err != nil {
-		return err
-	}
-	c.buffering = true
-	if err := hs.sendServerParameters(); err != nil {
-		return err
-	}
-	if err := hs.sendServerCertificate(); err != nil {
-		return err
-	}
-	if err := hs.sendServerFinished(); err != nil {
-		return err
-	}
-	// Note that at this point we could start sending application data without
-	// waiting for the client's second flight, but the application might not
-	// expect the lack of replay protection of the ClientHello parameters.
-	if _, err := c.flush(); err != nil {
-		return err
-	}
-	if err := hs.readClientCertificate(); err != nil {
-		return err
-	}
-	if err := hs.readClientFinished(); err != nil {
-		return err
-	}
-
-	c.handleCFEvent(hs.hsTimings)
-	atomic.StoreUint32(&c.handshakeStatus, 1)
-
-	return nil
-}
-
-func (hs *serverHandshakeStateTLS13) processClientHello() error {
-	c := hs.c
-
-	hs.hello = new(serverHelloMsg)
-
-	// TLS 1.3 froze the ServerHello.legacy_version field, and uses
-	// supported_versions instead. See RFC 8446, sections 4.1.3 and 4.2.1.
-	hs.hello.vers = VersionTLS12
-	hs.hello.supportedVersion = c.vers
-
-	if len(hs.clientHello.supportedVersions) == 0 {
-		c.sendAlert(alertIllegalParameter)
-		return errors.New("tls: client used the legacy version field to negotiate TLS 1.3")
-	}
-
-	// Abort if the client is doing a fallback and landing lower than what we
-	// support. See RFC 7507, which however does not specify the interaction
-	// with supported_versions. The only difference is that with
-	// supported_versions a client has a chance to attempt a [TLS 1.2, TLS 1.4]
-	// handshake in case TLS 1.3 is broken but 1.2 is not. Alas, in that case,
-	// it will have to drop the TLS_FALLBACK_SCSV protection if it falls back to
-	// TLS 1.2, because a TLS 1.3 server would abort here. The situation before
-	// supported_versions was not better because there was just no way to do a
-	// TLS 1.4 handshake without risking the server selecting TLS 1.3.
-	for _, id := range hs.clientHello.cipherSuites {
-		if id == TLS_FALLBACK_SCSV {
-			// Use c.vers instead of max(supported_versions) because an attacker
-			// could defeat this by adding an arbitrary high version otherwise.
-			if c.vers < c.config.maxSupportedVersion(roleServer) {
-				c.sendAlert(alertInappropriateFallback)
-				return errors.New("tls: client using inappropriate protocol fallback")
-			}
-			break
-		}
-	}
-
-	if len(hs.clientHello.compressionMethods) != 1 ||
-		hs.clientHello.compressionMethods[0] != compressionNone {
-		c.sendAlert(alertIllegalParameter)
-		return errors.New("tls: TLS 1.3 client supports illegal compression methods")
-	}
-
-	hs.hello.random = make([]byte, 32)
-	if _, err := io.ReadFull(c.config.rand(), hs.hello.random); err != nil {
-		c.sendAlert(alertInternalError)
-		return err
-	}
-
-	if len(hs.clientHello.secureRenegotiation) != 0 {
-		c.sendAlert(alertHandshakeFailure)
-		return errors.New("tls: initial handshake had non-empty renegotiation extension")
-	}
-
-	if hs.clientHello.earlyData {
-		// See RFC 8446, Section 4.2.10 for the complicated behavior required
-		// here. The scenario is that a different server at our address offered
-		// to accept early data in the past, which we can't handle. For now, all
-		// 0-RTT enabled session tickets need to expire before a Go server can
-		// replace a server or join a pool. That's the same requirement that
-		// applies to mixing or replacing with any TLS 1.2 server.
-		c.sendAlert(alertUnsupportedExtension)
-		return errors.New("tls: client sent unexpected early data")
-	}
-
-	hs.hello.sessionId = hs.clientHello.sessionId
-	hs.hello.compressionMethod = compressionNone
-
-	preferenceList := defaultCipherSuitesTLS13
-	if !hasAESGCMHardwareSupport || !aesgcmPreferred(hs.clientHello.cipherSuites) {
-		preferenceList = defaultCipherSuitesTLS13NoAES
-	}
-	for _, suiteID := range preferenceList {
-		hs.suite = mutualCipherSuiteTLS13(hs.clientHello.cipherSuites, suiteID)
-		if hs.suite != nil {
-			break
-		}
-	}
-	if hs.suite == nil {
-		c.sendAlert(alertHandshakeFailure)
-		return errors.New("tls: no cipher suite supported by both client and server")
-	}
-	c.cipherSuite = hs.suite.id
-	hs.hello.cipherSuite = hs.suite.id
-	hs.transcript = hs.suite.hash.New()
-
-	// Resolve the server's preference for the ECDHE group.
-	supportedCurves := c.config.curvePreferences()
-	if testingTriggerHRR {
-		// A HelloRetryRequest (HRR) is sent if the client does not offer a key
-		// share for a curve supported by the server. To trigger this condition
-		// intentionally, we compute the set of ECDHE groups supported by both
-		// the client and server but for which the client did not offer a key
-		// share.
-		m := make(map[CurveID]bool)
-		for _, serverGroup := range c.config.curvePreferences() {
-			for _, clientGroup := range hs.clientHello.supportedCurves {
-				if clientGroup == serverGroup {
-					m[clientGroup] = true
-				}
-			}
-		}
-		for _, ks := range hs.clientHello.keyShares {
-			delete(m, ks.group)
-		}
-		supportedCurves = nil
-		for group := range m {
-			supportedCurves = append(supportedCurves, group)
-		}
-		if len(supportedCurves) == 0 {
-			// This occurs if the client offered a key share for each mutually
-			// supported group.
-			panic("failed to trigger HelloRetryRequest")
-		}
-	}
-
-	// Pick the ECDHE group in server preference order, but give priority to
-	// groups with a key share, to avoid a HelloRetryRequest round-trip.
-	var selectedGroup CurveID
-	var clientKeyShare *keyShare
-GroupSelection:
-	for _, preferredGroup := range supportedCurves {
-		for _, ks := range hs.clientHello.keyShares {
-			if ks.group == preferredGroup {
-				selectedGroup = ks.group
-				clientKeyShare = &ks
-				break GroupSelection
-			}
-		}
-		if selectedGroup != 0 {
-			continue
-		}
-		for _, group := range hs.clientHello.supportedCurves {
-			if group == preferredGroup {
-				selectedGroup = group
-				break
-			}
-		}
-	}
-	if selectedGroup == 0 {
-		c.sendAlert(alertHandshakeFailure)
-		return errors.New("tls: no ECDHE curve supported by both client and server")
-	}
-	if clientKeyShare == nil {
-		if err := hs.doHelloRetryRequest(selectedGroup); err != nil {
-			return err
-		}
-		clientKeyShare = &hs.clientHello.keyShares[0]
-	}
-
-	if _, ok := curveForCurveID(selectedGroup); selectedGroup != X25519 && curveIdToCirclScheme(selectedGroup) == nil && !ok {
-		c.sendAlert(alertInternalError)
-		return errors.New("tls: CurvePreferences includes unsupported curve")
-	}
-	if kem := curveIdToCirclScheme(selectedGroup); kem != nil {
-		ct, ss, alert, err := encapsulateForKem(kem, c.config.rand(), clientKeyShare.data)
-		if err != nil {
-			c.sendAlert(alert)
-			return fmt.Errorf("%s encap: %w", kem.Name(), err)
-		}
-		hs.hello.serverShare = keyShare{group: selectedGroup, data: ct}
-		hs.sharedKey = ss
-	} else {
-		params, err := generateECDHEParameters(c.config.rand(), selectedGroup)
-		if err != nil {
-			c.sendAlert(alertInternalError)
-			return err
-		}
-		hs.hello.serverShare = keyShare{group: selectedGroup, data: params.PublicKey()}
-		hs.sharedKey = params.SharedKey(clientKeyShare.data)
-	}
-	if hs.sharedKey == nil {
-		c.sendAlert(alertIllegalParameter)
-		return errors.New("tls: invalid client key share")
-	}
-
-	c.serverName = hs.clientHello.serverName
-	c.handleCFEvent(CFEventTLSNegotiatedNamedKEX{
-		KEX: selectedGroup,
-	})
-
-	hs.hsTimings.ProcessClientHello = hs.hsTimings.elapsedTime()
-
-	return nil
-}
-
-func (hs *serverHandshakeStateTLS13) checkForResumption() error {
-	c := hs.c
-
-	if c.config.SessionTicketsDisabled || c.config.ECHEnabled {
-		return nil
-	}
-
-	modeOK := false
-	for _, mode := range hs.clientHello.pskModes {
-		if mode == pskModeDHE {
-			modeOK = true
-			break
-		}
-	}
-	if !modeOK {
-		return nil
-	}
-
-	if len(hs.clientHello.pskIdentities) != len(hs.clientHello.pskBinders) {
-		c.sendAlert(alertIllegalParameter)
-		return errors.New("tls: invalid or missing PSK binders")
-	}
-	if len(hs.clientHello.pskIdentities) == 0 {
-		return nil
-	}
-
-	for i, identity := range hs.clientHello.pskIdentities {
-		if i >= maxClientPSKIdentities {
-			break
-		}
-
-		plaintext, _ := c.decryptTicket(identity.label)
-		if plaintext == nil {
-			continue
-		}
-		sessionState := new(sessionStateTLS13)
-		if ok := sessionState.unmarshal(plaintext); !ok {
-			continue
-		}
-
-		createdAt := time.Unix(int64(sessionState.createdAt), 0)
-		if c.config.time().Sub(createdAt) > maxSessionTicketLifetime {
-			continue
-		}
-
-		// We don't check the obfuscated ticket age because it's affected by
-		// clock skew and it's only a freshness signal useful for shrinking the
-		// window for replay attacks, which don't affect us as we don't do 0-RTT.
-
-		pskSuite := cipherSuiteTLS13ByID(sessionState.cipherSuite)
-		if pskSuite == nil || pskSuite.hash != hs.suite.hash {
-			continue
-		}
-
-		// PSK connections don't re-establish client certificates, but carry
-		// them over in the session ticket. Ensure the presence of client certs
-		// in the ticket is consistent with the configured requirements.
-		sessionHasClientCerts := len(sessionState.certificate.Certificate) != 0
-		needClientCerts := requiresClientCert(c.config.ClientAuth)
-		if needClientCerts && !sessionHasClientCerts {
-			continue
-		}
-		if sessionHasClientCerts && c.config.ClientAuth == NoClientCert {
-			continue
-		}
-
-		psk := hs.suite.expandLabel(sessionState.resumptionSecret, "resumption",
-			nil, hs.suite.hash.Size())
-		hs.earlySecret = hs.suite.extract(psk, nil)
-		binderKey := hs.suite.deriveSecret(hs.earlySecret, resumptionBinderLabel, nil)
-		// Clone the transcript in case a HelloRetryRequest was recorded.
-		transcript := cloneHash(hs.transcript, hs.suite.hash)
-		if transcript == nil {
-			c.sendAlert(alertInternalError)
-			return errors.New("tls: internal error: failed to clone hash")
-		}
-		transcript.Write(hs.clientHello.marshalWithoutBinders())
-		pskBinder := hs.suite.finishedHash(binderKey, transcript)
-		if !hmac.Equal(hs.clientHello.pskBinders[i], pskBinder) {
-			c.sendAlert(alertDecryptError)
-			return errors.New("tls: invalid PSK binder")
-		}
-
-		c.didResume = true
-		if err := c.processCertsFromClient(sessionState.certificate); err != nil {
-			return err
-		}
-
-		hs.hello.selectedIdentityPresent = true
-		hs.hello.selectedIdentity = uint16(i)
-		hs.usingPSK = true
-		return nil
-	}
-
-	return nil
-}
-
-// cloneHash uses the encoding.BinaryMarshaler and encoding.BinaryUnmarshaler
-// interfaces implemented by standard library hashes to clone the state of in
-// to a new instance of h. It returns nil if the operation fails.
-func cloneHash(in hash.Hash, h crypto.Hash) hash.Hash {
-	// Recreate the interface to avoid importing encoding.
-	type binaryMarshaler interface {
-		MarshalBinary() (data []byte, err error)
-		UnmarshalBinary(data []byte) error
-	}
-	marshaler, ok := in.(binaryMarshaler)
-	if !ok {
-		return nil
-	}
-	state, err := marshaler.MarshalBinary()
-	if err != nil {
-		return nil
-	}
-	out := h.New()
-	unmarshaler, ok := out.(binaryMarshaler)
-	if !ok {
-		return nil
-	}
-	if err := unmarshaler.UnmarshalBinary(state); err != nil {
-		return nil
-	}
-	return out
-}
-
-// getDelegatedCredential will return a Delegated Credential pair (a Delegated
-// Credential and its private key) for the given ClientHelloInfo, defaulting to
-// the first element of cert.DelegatedCredentialPair.
-// The returned Delegated Credential could be invalid for usage in the handshake.
-// Returns an error if there are no delegated credentials or if the one found
-// cannot be used for the current connection.
-func getDelegatedCredential(clientHello *ClientHelloInfo, cert *Certificate) (*DelegatedCredentialPair, error) {
-	if len(cert.DelegatedCredentials) == 0 {
-		return nil, errors.New("no Delegated Credential found")
-	}
-
-	for _, dcPair := range cert.DelegatedCredentials {
-		// The client must have sent the signature_algorithms in the DC extension: ensure it supports
-		// schemes we can use with this delegated credential.
-		if len(clientHello.SignatureSchemesDC) > 0 {
-			if _, err := selectSignatureSchemeDC(VersionTLS13, dcPair.DC, clientHello.SignatureSchemes, clientHello.SignatureSchemesDC); err == nil {
-				return &dcPair, nil
-			}
-		}
-	}
-
-	// No delegated credential can be returned.
-	return nil, errors.New("no valid Delegated Credential found")
-}
-
-func (hs *serverHandshakeStateTLS13) pickCertificate() error {
-	c := hs.c
-
-	// Only one of PSK and certificates are used at a time.
-	if hs.usingPSK {
-		return nil
-	}
-
-	// signature_algorithms is required in TLS 1.3. See RFC 8446, Section 4.2.3.
-	if len(hs.clientHello.supportedSignatureAlgorithms) == 0 {
-		return c.sendAlert(alertMissingExtension)
-	}
-
-	certificate, err := c.config.getCertificate(clientHelloInfo(hs.ctx, c, hs.clientHello))
-	if err != nil {
-		if err == errNoCertificates {
-			c.sendAlert(alertUnrecognizedName)
-		} else {
-			c.sendAlert(alertInternalError)
-		}
-		return err
-	}
-
-	hs.sigAlg, err = selectSignatureScheme(c.vers, certificate, hs.clientHello.supportedSignatureAlgorithms)
-	if err != nil {
-		// getCertificate returned a certificate that is unsupported or
-		// incompatible with the client's signature algorithms.
-		c.sendAlert(alertHandshakeFailure)
-		return err
-	}
-
-	hs.cert = certificate
-
-	if hs.clientHello.delegatedCredentialSupported && len(hs.clientHello.supportedSignatureAlgorithmsDC) > 0 {
-		// getDelegatedCredential selects a delegated credential that the client has advertised support for, if possible.
-		delegatedCredentialPair, err := getDelegatedCredential(clientHelloInfo(hs.ctx, c, hs.clientHello), hs.cert)
-		if err != nil {
-			// a Delegated Credential was not found. Fallback to the certificate.
-			return nil
-		}
-		if delegatedCredentialPair.DC != nil && delegatedCredentialPair.PrivateKey != nil {
-			// Even if the Delegated Credential has already been marshalled, be sure it is the correct one.
-			delegatedCredentialPair.DC.raw, err = delegatedCredentialPair.DC.Marshal()
-			if err != nil {
-				// invalid Delegated Credential. Fallback to the certificate.
-				return nil
-			}
-			hs.sigAlg = delegatedCredentialPair.DC.cred.expCertVerfAlgo
-
-			hs.cert.PrivateKey = delegatedCredentialPair.PrivateKey
-			hs.cert.DelegatedCredential = delegatedCredentialPair.DC.raw
-		}
-	}
-	return nil
-}
-
-// sendDummyChangeCipherSpec sends a ChangeCipherSpec record for compatibility
-// with middleboxes that didn't implement TLS correctly. See RFC 8446, Appendix D.4.
-func (hs *serverHandshakeStateTLS13) sendDummyChangeCipherSpec() error {
-	if hs.sentDummyCCS {
-		return nil
-	}
-	hs.sentDummyCCS = true
-
-	_, err := hs.c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
-	return err
-}
-
-func (hs *serverHandshakeStateTLS13) doHelloRetryRequest(selectedGroup CurveID) error {
-	c := hs.c
-
-	c.handleCFEvent(CFEventTLS13HRR{})
-
-	// The first ClientHello gets double-hashed into the transcript upon a
-	// HelloRetryRequest. See RFC 8446, Section 4.4.1.
-	hs.transcript.Write(hs.clientHello.marshal())
-	chHash := hs.transcript.Sum(nil)
-	hs.transcript.Reset()
-	hs.transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))})
-	hs.transcript.Write(chHash)
-
-	helloRetryRequest := &serverHelloMsg{
-		vers:              hs.hello.vers,
-		random:            helloRetryRequestRandom,
-		sessionId:         hs.hello.sessionId,
-		cipherSuite:       hs.hello.cipherSuite,
-		compressionMethod: hs.hello.compressionMethod,
-		supportedVersion:  hs.hello.supportedVersion,
-		selectedGroup:     selectedGroup,
-	}
-
-	// Decide whether to send "encrypted_client_hello" extension.
-	if hs.echIsInner() {
-		// Confirm ECH acceptance if this is the inner handshake.
-		echAcceptConfHRRTranscript := cloneHash(hs.transcript, hs.suite.hash)
-		if echAcceptConfHRRTranscript == nil {
-			c.sendAlert(alertInternalError)
-			return errors.New("tls: internal error: failed to clone hash")
-		}
-
-		helloRetryRequest.ech = zeros[:8]
-		echAcceptConfHRR := helloRetryRequest.marshal()
-		echAcceptConfHRRTranscript.Write(echAcceptConfHRR)
-		echAcceptConfHRRSignal := hs.suite.expandLabel(
-			hs.suite.extract(hs.clientHello.random, nil),
-			echAcceptConfHRRLabel,
-			echAcceptConfHRRTranscript.Sum(nil),
-			8)
-
-		helloRetryRequest.ech = echAcceptConfHRRSignal
-		helloRetryRequest.raw = nil
-	} else if c.ech.greased {
-		// draft-ietf-tls-esni-13, Section 7.1:
-		//
-		// If sending a HelloRetryRequest, the server MAY include an
-		// "encrypted_client_hello" extension with a payload of 8 random bytes;
-		// see Section 10.9.4 for details.
-		helloRetryRequest.ech = make([]byte, 8)
-		if _, err := io.ReadFull(c.config.rand(), helloRetryRequest.ech); err != nil {
-			c.sendAlert(alertInternalError)
-			return fmt.Errorf("tls: internal error: rng failure: %s", err)
-		}
-	}
-
-	hs.transcript.Write(helloRetryRequest.marshal())
-	if _, err := c.writeRecord(recordTypeHandshake, helloRetryRequest.marshal()); err != nil {
-		return err
-	}
-
-	if err := hs.sendDummyChangeCipherSpec(); err != nil {
-		return err
-	}
-
-	msg, err := c.readHandshake()
-	if err != nil {
-		return err
-	}
-
-	clientHello, ok := msg.(*clientHelloMsg)
-	if !ok {
-		c.sendAlert(alertUnexpectedMessage)
-		return unexpectedMessageError(clientHello, msg)
-	}
-
-	clientHello, err = c.echAcceptOrReject(clientHello, true) // afterHRR == true
-	if err != nil {
-		return fmt.Errorf("tls: %s", err) // Alert sent
-	}
-
-	if len(clientHello.keyShares) != 1 || clientHello.keyShares[0].group != selectedGroup {
-		c.sendAlert(alertIllegalParameter)
-		return errors.New("tls: client sent invalid key share in second ClientHello")
-	}
-
-	if clientHello.earlyData {
-		c.sendAlert(alertIllegalParameter)
-		return errors.New("tls: client indicated early data in second ClientHello")
-	}
-
-	if illegalClientHelloChange(clientHello, hs.clientHello) {
-		c.sendAlert(alertIllegalParameter)
-		return errors.New("tls: client illegally modified second ClientHello")
-	}
-
-	hs.clientHello = clientHello
-	return nil
-}
-
-// illegalClientHelloChange reports whether the two ClientHello messages are
-// different, with the exception of the changes allowed before and after a
-// HelloRetryRequest. See RFC 8446, Section 4.1.2.
-func illegalClientHelloChange(ch, ch1 *clientHelloMsg) bool {
-	if len(ch.supportedVersions) != len(ch1.supportedVersions) ||
-		len(ch.cipherSuites) != len(ch1.cipherSuites) ||
-		len(ch.supportedCurves) != len(ch1.supportedCurves) ||
-		len(ch.supportedSignatureAlgorithms) != len(ch1.supportedSignatureAlgorithms) ||
-		len(ch.supportedSignatureAlgorithmsCert) != len(ch1.supportedSignatureAlgorithmsCert) ||
-		len(ch.supportedSignatureAlgorithmsDC) != len(ch1.supportedSignatureAlgorithmsDC) ||
-		len(ch.alpnProtocols) != len(ch1.alpnProtocols) {
-		return true
-	}
-	for i := range ch.supportedVersions {
-		if ch.supportedVersions[i] != ch1.supportedVersions[i] {
-			return true
-		}
-	}
-	for i := range ch.cipherSuites {
-		if ch.cipherSuites[i] != ch1.cipherSuites[i] {
-			return true
-		}
-	}
-	for i := range ch.supportedCurves {
-		if ch.supportedCurves[i] != ch1.supportedCurves[i] {
-			return true
-		}
-	}
-	for i := range ch.supportedSignatureAlgorithms {
-		if ch.supportedSignatureAlgorithms[i] != ch1.supportedSignatureAlgorithms[i] {
-			return true
-		}
-	}
-	for i := range ch.supportedSignatureAlgorithmsCert {
-		if ch.supportedSignatureAlgorithmsCert[i] != ch1.supportedSignatureAlgorithmsCert[i] {
-			return true
-		}
-	}
-	for i := range ch.supportedSignatureAlgorithmsDC {
-		if ch.supportedSignatureAlgorithmsDC[i] != ch1.supportedSignatureAlgorithmsDC[i] {
-			return true
-		}
-	}
-	for i := range ch.alpnProtocols {
-		if ch.alpnProtocols[i] != ch1.alpnProtocols[i] {
-			return true
-		}
-	}
-	return ch.vers != ch1.vers ||
-		!bytes.Equal(ch.random, ch1.random) ||
-		!bytes.Equal(ch.sessionId, ch1.sessionId) ||
-		!bytes.Equal(ch.compressionMethods, ch1.compressionMethods) ||
-		ch.serverName != ch1.serverName ||
-		ch.ocspStapling != ch1.ocspStapling ||
-		!bytes.Equal(ch.supportedPoints, ch1.supportedPoints) ||
-		ch.ticketSupported != ch1.ticketSupported ||
-		!bytes.Equal(ch.sessionTicket, ch1.sessionTicket) ||
-		ch.secureRenegotiationSupported != ch1.secureRenegotiationSupported ||
-		!bytes.Equal(ch.secureRenegotiation, ch1.secureRenegotiation) ||
-		ch.delegatedCredentialSupported != ch1.delegatedCredentialSupported ||
-		ch.scts != ch1.scts ||
-		!bytes.Equal(ch.cookie, ch1.cookie) ||
-		!bytes.Equal(ch.pskModes, ch1.pskModes)
-}
-
-func (hs *serverHandshakeStateTLS13) sendServerParameters() error {
-	c := hs.c
-
-	// Confirm ECH acceptance.
-	if hs.echIsInner() {
-		// Clear the last 8 bytes of the ServerHello.random in preparation for
-		// computing the confirmation hint.
-		copy(hs.hello.random[24:], zeros[:8])
-
-		// Set the last 8 bytes of ServerHello.random to a string derived from
-		// the inner handshake.
-		echAcceptConfTranscript := cloneHash(hs.transcript, hs.suite.hash)
-		if echAcceptConfTranscript == nil {
-			c.sendAlert(alertInternalError)
-			return errors.New("tls: internal error: failed to clone hash")
-		}
-		echAcceptConfTranscript.Write(hs.clientHello.marshal())
-		echAcceptConfTranscript.Write(hs.hello.marshal())
-
-		echAcceptConf := hs.suite.expandLabel(
-			hs.suite.extract(hs.clientHello.random, nil),
-			echAcceptConfLabel,
-			echAcceptConfTranscript.Sum(nil),
-			8)
-
-		copy(hs.hello.random[24:], echAcceptConf)
-		hs.hello.raw = nil
-	}
-
-	hs.transcript.Write(hs.clientHello.marshal())
-	hs.transcript.Write(hs.hello.marshal())
-	if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil {
-		return err
-	}
-
-	hs.hsTimings.WriteServerHello = hs.hsTimings.elapsedTime()
-
-	if err := hs.sendDummyChangeCipherSpec(); err != nil {
-		return err
-	}
-
-	earlySecret := hs.earlySecret
-	if earlySecret == nil {
-		earlySecret = hs.suite.extract(nil, nil)
-	}
-	hs.handshakeSecret = hs.suite.extract(hs.sharedKey,
-		hs.suite.deriveSecret(earlySecret, "derived", nil))
-
-	clientSecret := hs.suite.deriveSecret(hs.handshakeSecret,
-		clientHandshakeTrafficLabel, hs.transcript)
-	c.in.setTrafficSecret(hs.suite, clientSecret)
-	serverSecret := hs.suite.deriveSecret(hs.handshakeSecret,
-		serverHandshakeTrafficLabel, hs.transcript)
-	c.out.setTrafficSecret(hs.suite, serverSecret)
-
-	err := c.config.writeKeyLog(keyLogLabelClientHandshake, hs.clientHello.random, clientSecret)
-	if err != nil {
-		c.sendAlert(alertInternalError)
-		return err
-	}
-	err = c.config.writeKeyLog(keyLogLabelServerHandshake, hs.clientHello.random, serverSecret)
-	if err != nil {
-		c.sendAlert(alertInternalError)
-		return err
-	}
-
-	encryptedExtensions := new(encryptedExtensionsMsg)
-
-	selectedProto, err := negotiateALPN(c.config.NextProtos, hs.clientHello.alpnProtocols)
-	if err != nil {
-		c.sendAlert(alertNoApplicationProtocol)
-		return err
-	}
-	encryptedExtensions.alpnProtocol = selectedProto
-	c.clientProtocol = selectedProto
-
-	if !c.ech.accepted && len(c.ech.retryConfigs) > 0 {
-		encryptedExtensions.ech = c.ech.retryConfigs
-	}
-
-	hs.transcript.Write(encryptedExtensions.marshal())
-	if _, err := c.writeRecord(recordTypeHandshake, encryptedExtensions.marshal()); err != nil {
-		return err
-	}
-
-	hs.hsTimings.WriteEncryptedExtensions = hs.hsTimings.elapsedTime()
-
-	return nil
-}
-
-func (hs *serverHandshakeStateTLS13) requestClientCert() bool {
-	return hs.c.config.ClientAuth >= RequestClientCert && !hs.usingPSK
-}
-
-func (hs *serverHandshakeStateTLS13) sendServerCertificate() error {
-	c := hs.c
-
-	// Only one of PSK and certificates are used at a time.
-	if hs.usingPSK {
-		return nil
-	}
-
-	if hs.requestClientCert() {
-		// Request a client certificate
-		certReq := new(certificateRequestMsgTLS13)
-		certReq.ocspStapling = true
-		certReq.scts = true
-		certReq.supportedSignatureAlgorithms = c.config.supportedSignatureAlgorithms()
-		certReq.supportDelegatedCredential = c.config.SupportDelegatedCredential
-		certReq.supportedSignatureAlgorithmsDC = supportedSignatureAlgorithmsDC
-		if c.config.ClientCAs != nil {
-			certReq.certificateAuthorities = c.config.ClientCAs.Subjects()
-		}
-
-		hs.certReq = certReq
-		hs.transcript.Write(certReq.marshal())
-		if _, err := c.writeRecord(recordTypeHandshake, certReq.marshal()); err != nil {
-			return err
-		}
-	}
-
-	certMsg := new(certificateMsgTLS13)
-
-	certMsg.certificate = *hs.cert
-	certMsg.scts = hs.clientHello.scts && len(hs.cert.SignedCertificateTimestamps) > 0
-	certMsg.ocspStapling = hs.clientHello.ocspStapling && len(hs.cert.OCSPStaple) > 0
-	certMsg.delegatedCredential = hs.clientHello.delegatedCredentialSupported && len(hs.cert.DelegatedCredential) > 0
-
-	hs.transcript.Write(certMsg.marshal())
-	if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil {
-		return err
-	}
-
-	hs.hsTimings.WriteCertificate = hs.hsTimings.elapsedTime()
-
-	certVerifyMsg := new(certificateVerifyMsg)
-	certVerifyMsg.hasSignatureAlgorithm = true
-	certVerifyMsg.signatureAlgorithm = hs.sigAlg
-	sigType, sigHash, err := typeAndHashFromSignatureScheme(certVerifyMsg.signatureAlgorithm)
-	if err != nil {
-		return c.sendAlert(alertInternalError)
-	}
-
-	signed := signedMessage(sigHash, serverSignatureContext, hs.transcript)
-	signOpts := crypto.SignerOpts(sigHash)
-	if sigType == signatureRSAPSS {
-		signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash}
-	}
-	sig, err := hs.cert.PrivateKey.(crypto.Signer).Sign(c.config.rand(), signed, signOpts)
-	if err != nil {
-		public := hs.cert.PrivateKey.(crypto.Signer).Public()
-		if rsaKey, ok := public.(*rsa.PublicKey); ok && sigType == signatureRSAPSS &&
-			rsaKey.N.BitLen()/8 < sigHash.Size()*2+2 { // key too small for RSA-PSS
-			c.sendAlert(alertHandshakeFailure)
-		} else {
-			c.sendAlert(alertInternalError)
-		}
-		return errors.New("tls: failed to sign handshake: " + err.Error())
-	}
-	certVerifyMsg.signature = sig
-
-	hs.transcript.Write(certVerifyMsg.marshal())
-	if _, err := c.writeRecord(recordTypeHandshake, certVerifyMsg.marshal()); err != nil {
-		return err
-	}
-
-	hs.hsTimings.WriteCertificateVerify = hs.hsTimings.elapsedTime()
-
-	return nil
-}
-
-func (hs *serverHandshakeStateTLS13) sendServerFinished() error {
-	c := hs.c
-
-	finished := &finishedMsg{
-		verifyData: hs.suite.finishedHash(c.out.trafficSecret, hs.transcript),
-	}
-
-	hs.transcript.Write(finished.marshal())
-	if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil {
-		return err
-	}
-
-	hs.hsTimings.WriteServerFinished = hs.hsTimings.elapsedTime()
-
-	// Derive secrets that take context through the server Finished.
-
-	hs.masterSecret = hs.suite.extract(nil,
-		hs.suite.deriveSecret(hs.handshakeSecret, "derived", nil))
-
-	hs.trafficSecret = hs.suite.deriveSecret(hs.masterSecret,
-		clientApplicationTrafficLabel, hs.transcript)
-	serverSecret := hs.suite.deriveSecret(hs.masterSecret,
-		serverApplicationTrafficLabel, hs.transcript)
-	c.out.setTrafficSecret(hs.suite, serverSecret)
-
-	err := c.config.writeKeyLog(keyLogLabelClientTraffic, hs.clientHello.random, hs.trafficSecret)
-	if err != nil {
-		c.sendAlert(alertInternalError)
-		return err
-	}
-	err = c.config.writeKeyLog(keyLogLabelServerTraffic, hs.clientHello.random, serverSecret)
-	if err != nil {
-		c.sendAlert(alertInternalError)
-		return err
-	}
-
-	c.ekm = hs.suite.exportKeyingMaterial(hs.masterSecret, hs.transcript)
-
-	// If we did not request client certificates, at this point we can
-	// precompute the client finished and roll the transcript forward to send
-	// session tickets in our first flight.
-	if !hs.requestClientCert() {
-		if err := hs.sendSessionTickets(); err != nil {
-			return err
-		}
-	}
-
-	return nil
-}
-
-func (hs *serverHandshakeStateTLS13) shouldSendSessionTickets() bool {
-	if hs.c.config.SessionTicketsDisabled || hs.c.config.ECHEnabled {
-		return false
-	}
-
-	// Don't send tickets the client wouldn't use. See RFC 8446, Section 4.2.9.
-	for _, pskMode := range hs.clientHello.pskModes {
-		if pskMode == pskModeDHE {
-			return true
-		}
-	}
-	return false
-}
-
-func (hs *serverHandshakeStateTLS13) sendSessionTickets() error {
-	c := hs.c
-
-	hs.clientFinished = hs.suite.finishedHash(c.in.trafficSecret, hs.transcript)
-	finishedMsg := &finishedMsg{
-		verifyData: hs.clientFinished,
-	}
-	hs.transcript.Write(finishedMsg.marshal())
-
-	if !hs.shouldSendSessionTickets() {
-		return nil
-	}
-
-	resumptionSecret := hs.suite.deriveSecret(hs.masterSecret,
-		resumptionLabel, hs.transcript)
-
-	m := new(newSessionTicketMsgTLS13)
-
-	var certsFromClient [][]byte
-	for _, cert := range c.peerCertificates {
-		certsFromClient = append(certsFromClient, cert.Raw)
-	}
-	state := sessionStateTLS13{
-		cipherSuite:      hs.suite.id,
-		createdAt:        uint64(c.config.time().Unix()),
-		resumptionSecret: resumptionSecret,
-		certificate: Certificate{
-			Certificate:                 certsFromClient,
-			OCSPStaple:                  c.ocspResponse,
-			SignedCertificateTimestamps: c.scts,
-		},
-	}
-	var err error
-	m.label, err = c.encryptTicket(state.marshal())
-	if err != nil {
-		return err
-	}
-	m.lifetime = uint32(maxSessionTicketLifetime / time.Second)
-
-	// ticket_age_add is a random 32-bit value. See RFC 8446, section 4.6.1
-	// The value is not stored anywhere; we never need to check the ticket age
-	// because 0-RTT is not supported.
-	ageAdd := make([]byte, 4)
-	_, err = hs.c.config.rand().Read(ageAdd)
-	if err != nil {
-		return err
-	}
-	m.ageAdd = binary.LittleEndian.Uint32(ageAdd)
-
-	// ticket_nonce, which must be unique per connection, is always left at
-	// zero because we only ever send one ticket per connection.
-
-	if _, err := c.writeRecord(recordTypeHandshake, m.marshal()); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func (hs *serverHandshakeStateTLS13) readClientCertificate() error {
-	c := hs.c
-
-	if !hs.requestClientCert() {
-		// Make sure the connection is still being verified whether or not
-		// the server requested a client certificate.
-		if c.config.VerifyConnection != nil {
-			if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil {
-				c.sendAlert(alertBadCertificate)
-				return err
-			}
-		}
-		return nil
-	}
-
-	// If we requested a client certificate, then the client must send a
-	// certificate message. If it's empty, no CertificateVerify is sent.
-
-	msg, err := c.readHandshake()
-	if err != nil {
-		return err
-	}
-
-	certMsg, ok := msg.(*certificateMsgTLS13)
-	if !ok {
-		c.sendAlert(alertUnexpectedMessage)
-		return unexpectedMessageError(certMsg, msg)
-	}
-	hs.transcript.Write(certMsg.marshal())
-
-	if err := c.processCertsFromClient(certMsg.certificate); err != nil {
-		return err
-	}
-
-	if c.config.VerifyConnection != nil {
-		if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil {
-			c.sendAlert(alertBadCertificate)
-			return err
-		}
-	}
-
-	hs.hsTimings.ReadCertificate = hs.hsTimings.elapsedTime()
-
-	if len(certMsg.certificate.Certificate) != 0 {
-		msg, err = c.readHandshake()
-		if err != nil {
-			return err
-		}
-
-		certVerify, ok := msg.(*certificateVerifyMsg)
-		if !ok {
-			c.sendAlert(alertUnexpectedMessage)
-			return unexpectedMessageError(certVerify, msg)
-		}
-
-		// See RFC 8446, Section 4.4.3.
-		if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, c.config.supportedSignatureAlgorithms()) {
-			c.sendAlert(alertIllegalParameter)
-			return errors.New("tls: client certificate used with invalid signature algorithm")
-		}
-		sigType, sigHash, err := typeAndHashFromSignatureScheme(certVerify.signatureAlgorithm)
-		if err != nil {
-			return c.sendAlert(alertInternalError)
-		}
-		if sigType == signaturePKCS1v15 || sigHash == crypto.SHA1 {
-			c.sendAlert(alertIllegalParameter)
-			return errors.New("tls: client certificate used with invalid signature algorithm")
-		}
-
-		if certMsg.delegatedCredential {
-			if err := hs.processDelegatedCredentialFromClient(certMsg.certificate.DelegatedCredential, certVerify); err != nil {
-				return err
-			}
-		}
-
-		pk := c.peerCertificates[0].PublicKey
-		if c.verifiedDC != nil {
-			pk = c.verifiedDC.cred.publicKey
-		}
-
-		signed := signedMessage(sigHash, clientSignatureContext, hs.transcript)
-		if err := verifyHandshakeSignature(sigType, pk, sigHash, signed, certVerify.signature); err != nil {
-			c.sendAlert(alertDecryptError)
-			return errors.New("tls: invalid signature by the client certificate: " + err.Error())
-		}
-
-		hs.transcript.Write(certVerify.marshal())
-	}
-
-	hs.hsTimings.ReadCertificateVerify = hs.hsTimings.elapsedTime()
-
-	// If we waited until the client certificates to send session tickets, we
-	// are ready to do it now.
-	if err := hs.sendSessionTickets(); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func (hs *serverHandshakeStateTLS13) readClientFinished() error {
-	c := hs.c
-
-	msg, err := c.readHandshake()
-	if err != nil {
-		return err
-	}
-
-	finished, ok := msg.(*finishedMsg)
-	if !ok {
-		c.sendAlert(alertUnexpectedMessage)
-		return unexpectedMessageError(finished, msg)
-	}
-
-	if !hmac.Equal(hs.clientFinished, finished.verifyData) {
-		c.sendAlert(alertDecryptError)
-		return errors.New("tls: invalid client finished hash")
-	}
-
-	hs.hsTimings.ReadClientFinished = hs.hsTimings.elapsedTime()
-
-	c.in.setTrafficSecret(hs.suite, hs.trafficSecret)
-
-	return nil
-}

+ 0 - 42
transport/cloudflaretls/hpke.go

@@ -1,42 +0,0 @@
-// Copyright 2020 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 (
-	"errors"
-	"fmt"
-
-	"github.com/cloudflare/circl/hpke"
-)
-
-// The mandatory-to-implement HPKE cipher suite for use with the ECH extension.
-var defaultHPKESuite hpke.Suite
-
-func init() {
-	var err error
-	defaultHPKESuite, err = hpkeAssembleSuite(
-		uint16(hpke.KEM_X25519_HKDF_SHA256),
-		uint16(hpke.KDF_HKDF_SHA256),
-		uint16(hpke.AEAD_AES128GCM),
-	)
-	if err != nil {
-		panic(fmt.Sprintf("hpke: mandatory-to-implement cipher suite not supported: %s", err))
-	}
-}
-
-func hpkeAssembleSuite(kemId, kdfId, aeadId uint16) (hpke.Suite, error) {
-	kem := hpke.KEM(kemId)
-	if !kem.IsValid() {
-		return hpke.Suite{}, errors.New("KEM is not supported")
-	}
-	kdf := hpke.KDF(kdfId)
-	if !kdf.IsValid() {
-		return hpke.Suite{}, errors.New("KDF is not supported")
-	}
-	aead := hpke.AEAD(aeadId)
-	if !aead.IsValid() {
-		return hpke.Suite{}, errors.New("AEAD is not supported")
-	}
-	return hpke.NewSuite(kem, kdf, aead), nil
-}

+ 0 - 359
transport/cloudflaretls/key_agreement.go

@@ -1,359 +0,0 @@
-// Copyright 2010 The Go Authors. 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 (
-	"crypto"
-	"crypto/md5"
-	"crypto/rsa"
-	"crypto/sha1"
-	"crypto/x509"
-	"errors"
-	"fmt"
-	"io"
-)
-
-// a keyAgreement implements the client and server side of a TLS key agreement
-// protocol by generating and processing key exchange messages.
-type keyAgreement interface {
-	// On the server side, the first two methods are called in order.
-
-	// In the case that the key agreement protocol doesn't use a
-	// ServerKeyExchange message, generateServerKeyExchange can return nil,
-	// nil.
-	generateServerKeyExchange(*Config, *Certificate, *clientHelloMsg, *serverHelloMsg) (*serverKeyExchangeMsg, error)
-	processClientKeyExchange(*Config, *Certificate, *clientKeyExchangeMsg, uint16) ([]byte, error)
-
-	// On the client side, the next two methods are called in order.
-
-	// This method may not be called if the server doesn't send a
-	// ServerKeyExchange message.
-	processServerKeyExchange(*Config, *clientHelloMsg, *serverHelloMsg, *x509.Certificate, *serverKeyExchangeMsg) error
-	generateClientKeyExchange(*Config, *clientHelloMsg, *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error)
-}
-
-var (
-	errClientKeyExchange = errors.New("tls: invalid ClientKeyExchange message")
-	errServerKeyExchange = errors.New("tls: invalid ServerKeyExchange message")
-)
-
-// rsaKeyAgreement implements the standard TLS key agreement where the client
-// encrypts the pre-master secret to the server's public key.
-type rsaKeyAgreement struct{}
-
-func (ka rsaKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
-	return nil, nil
-}
-
-func (ka rsaKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
-	if len(ckx.ciphertext) < 2 {
-		return nil, errClientKeyExchange
-	}
-	ciphertextLen := int(ckx.ciphertext[0])<<8 | int(ckx.ciphertext[1])
-	if ciphertextLen != len(ckx.ciphertext)-2 {
-		return nil, errClientKeyExchange
-	}
-	ciphertext := ckx.ciphertext[2:]
-
-	priv, ok := cert.PrivateKey.(crypto.Decrypter)
-	if !ok {
-		return nil, errors.New("tls: certificate private key does not implement crypto.Decrypter")
-	}
-	// Perform constant time RSA PKCS #1 v1.5 decryption
-	preMasterSecret, err := priv.Decrypt(config.rand(), ciphertext, &rsa.PKCS1v15DecryptOptions{SessionKeyLen: 48})
-	if err != nil {
-		return nil, err
-	}
-	// We don't check the version number in the premaster secret. For one,
-	// by checking it, we would leak information about the validity of the
-	// encrypted pre-master secret. Secondly, it provides only a small
-	// benefit against a downgrade attack and some implementations send the
-	// wrong version anyway. See the discussion at the end of section
-	// 7.4.7.1 of RFC 4346.
-	return preMasterSecret, nil
-}
-
-func (ka rsaKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error {
-	return errors.New("tls: unexpected ServerKeyExchange")
-}
-
-func (ka rsaKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
-	preMasterSecret := make([]byte, 48)
-	preMasterSecret[0] = byte(clientHello.vers >> 8)
-	preMasterSecret[1] = byte(clientHello.vers)
-	_, err := io.ReadFull(config.rand(), preMasterSecret[2:])
-	if err != nil {
-		return nil, nil, err
-	}
-
-	rsaKey, ok := cert.PublicKey.(*rsa.PublicKey)
-	if !ok {
-		return nil, nil, errors.New("tls: server certificate contains incorrect key type for selected ciphersuite")
-	}
-	encrypted, err := rsa.EncryptPKCS1v15(config.rand(), rsaKey, preMasterSecret)
-	if err != nil {
-		return nil, nil, err
-	}
-	ckx := new(clientKeyExchangeMsg)
-	ckx.ciphertext = make([]byte, len(encrypted)+2)
-	ckx.ciphertext[0] = byte(len(encrypted) >> 8)
-	ckx.ciphertext[1] = byte(len(encrypted))
-	copy(ckx.ciphertext[2:], encrypted)
-	return preMasterSecret, ckx, nil
-}
-
-// sha1Hash calculates a SHA1 hash over the given byte slices.
-func sha1Hash(slices [][]byte) []byte {
-	hsha1 := sha1.New()
-	for _, slice := range slices {
-		hsha1.Write(slice)
-	}
-	return hsha1.Sum(nil)
-}
-
-// md5SHA1Hash implements TLS 1.0's hybrid hash function which consists of the
-// concatenation of an MD5 and SHA1 hash.
-func md5SHA1Hash(slices [][]byte) []byte {
-	md5sha1 := make([]byte, md5.Size+sha1.Size)
-	hmd5 := md5.New()
-	for _, slice := range slices {
-		hmd5.Write(slice)
-	}
-	copy(md5sha1, hmd5.Sum(nil))
-	copy(md5sha1[md5.Size:], sha1Hash(slices))
-	return md5sha1
-}
-
-// hashForServerKeyExchange hashes the given slices and returns their digest
-// using the given hash function (for >= TLS 1.2) or using a default based on
-// the sigType (for earlier TLS versions). For Ed25519 signatures, which don't
-// do pre-hashing, it returns the concatenation of the slices.
-func hashForServerKeyExchange(sigType uint8, hashFunc crypto.Hash, version uint16, slices ...[]byte) []byte {
-	if sigType == signatureEd25519 || circlSchemeBySigType(sigType) != nil {
-		var signed []byte
-		for _, slice := range slices {
-			signed = append(signed, slice...)
-		}
-		return signed
-	}
-	if version >= VersionTLS12 {
-		h := hashFunc.New()
-		for _, slice := range slices {
-			h.Write(slice)
-		}
-		digest := h.Sum(nil)
-		return digest
-	}
-	if sigType == signatureECDSA {
-		return sha1Hash(slices)
-	}
-	return md5SHA1Hash(slices)
-}
-
-// ecdheKeyAgreement implements a TLS key agreement where the server
-// generates an ephemeral EC public/private key pair and signs it. The
-// pre-master secret is then calculated using ECDH. The signature may
-// be ECDSA, Ed25519 or RSA.
-type ecdheKeyAgreement struct {
-	version uint16
-	isRSA   bool
-	params  ecdheParameters
-
-	// ckx and preMasterSecret are generated in processServerKeyExchange
-	// and returned in generateClientKeyExchange.
-	ckx             *clientKeyExchangeMsg
-	preMasterSecret []byte
-}
-
-func (ka *ecdheKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
-	var curveID CurveID
-	for _, c := range clientHello.supportedCurves {
-		if config.supportsCurve(c) && curveIdToCirclScheme(c) == nil {
-			curveID = c
-			break
-		}
-	}
-
-	if curveID == 0 {
-		return nil, errors.New("tls: no supported elliptic curves offered")
-	}
-	if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok {
-		return nil, errors.New("tls: CurvePreferences includes unsupported curve")
-	}
-
-	params, err := generateECDHEParameters(config.rand(), curveID)
-	if err != nil {
-		return nil, err
-	}
-	ka.params = params
-
-	// See RFC 4492, Section 5.4.
-	ecdhePublic := params.PublicKey()
-	serverECDHEParams := make([]byte, 1+2+1+len(ecdhePublic))
-	serverECDHEParams[0] = 3 // named curve
-	serverECDHEParams[1] = byte(curveID >> 8)
-	serverECDHEParams[2] = byte(curveID)
-	serverECDHEParams[3] = byte(len(ecdhePublic))
-	copy(serverECDHEParams[4:], ecdhePublic)
-
-	priv, ok := cert.PrivateKey.(crypto.Signer)
-	if !ok {
-		return nil, fmt.Errorf("tls: certificate private key of type %T does not implement crypto.Signer", cert.PrivateKey)
-	}
-
-	var signatureAlgorithm SignatureScheme
-	var sigType uint8
-	var sigHash crypto.Hash
-	if ka.version >= VersionTLS12 {
-		signatureAlgorithm, err = selectSignatureScheme(ka.version, cert, clientHello.supportedSignatureAlgorithms)
-		if err != nil {
-			return nil, err
-		}
-		sigType, sigHash, err = typeAndHashFromSignatureScheme(signatureAlgorithm)
-		if err != nil {
-			return nil, err
-		}
-	} else {
-		sigType, sigHash, err = legacyTypeAndHashFromPublicKey(priv.Public())
-		if err != nil {
-			return nil, err
-		}
-	}
-	if (sigType == signaturePKCS1v15 || sigType == signatureRSAPSS) != ka.isRSA {
-		return nil, errors.New("tls: certificate cannot be used with the selected cipher suite")
-	}
-
-	signed := hashForServerKeyExchange(sigType, sigHash, ka.version, clientHello.random, hello.random, serverECDHEParams)
-
-	signOpts := crypto.SignerOpts(sigHash)
-	if sigType == signatureRSAPSS {
-		signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash}
-	}
-	sig, err := priv.Sign(config.rand(), signed, signOpts)
-	if err != nil {
-		return nil, errors.New("tls: failed to sign ECDHE parameters: " + err.Error())
-	}
-
-	skx := new(serverKeyExchangeMsg)
-	sigAndHashLen := 0
-	if ka.version >= VersionTLS12 {
-		sigAndHashLen = 2
-	}
-	skx.key = make([]byte, len(serverECDHEParams)+sigAndHashLen+2+len(sig))
-	copy(skx.key, serverECDHEParams)
-	k := skx.key[len(serverECDHEParams):]
-	if ka.version >= VersionTLS12 {
-		k[0] = byte(signatureAlgorithm >> 8)
-		k[1] = byte(signatureAlgorithm)
-		k = k[2:]
-	}
-	k[0] = byte(len(sig) >> 8)
-	k[1] = byte(len(sig))
-	copy(k[2:], sig)
-
-	return skx, nil
-}
-
-func (ka *ecdheKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
-	if len(ckx.ciphertext) == 0 || int(ckx.ciphertext[0]) != len(ckx.ciphertext)-1 {
-		return nil, errClientKeyExchange
-	}
-
-	preMasterSecret := ka.params.SharedKey(ckx.ciphertext[1:])
-	if preMasterSecret == nil {
-		return nil, errClientKeyExchange
-	}
-
-	return preMasterSecret, nil
-}
-
-func (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error {
-	if len(skx.key) < 4 {
-		return errServerKeyExchange
-	}
-	if skx.key[0] != 3 { // named curve
-		return errors.New("tls: server selected unsupported curve")
-	}
-	curveID := CurveID(skx.key[1])<<8 | CurveID(skx.key[2])
-
-	publicLen := int(skx.key[3])
-	if publicLen+4 > len(skx.key) {
-		return errServerKeyExchange
-	}
-	serverECDHEParams := skx.key[:4+publicLen]
-	publicKey := serverECDHEParams[4:]
-
-	sig := skx.key[4+publicLen:]
-	if len(sig) < 2 {
-		return errServerKeyExchange
-	}
-
-	if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok {
-		return errors.New("tls: server selected unsupported curve")
-	}
-
-	params, err := generateECDHEParameters(config.rand(), curveID)
-	if err != nil {
-		return err
-	}
-	ka.params = params
-
-	ka.preMasterSecret = params.SharedKey(publicKey)
-	if ka.preMasterSecret == nil {
-		return errServerKeyExchange
-	}
-
-	ourPublicKey := params.PublicKey()
-	ka.ckx = new(clientKeyExchangeMsg)
-	ka.ckx.ciphertext = make([]byte, 1+len(ourPublicKey))
-	ka.ckx.ciphertext[0] = byte(len(ourPublicKey))
-	copy(ka.ckx.ciphertext[1:], ourPublicKey)
-
-	var sigType uint8
-	var sigHash crypto.Hash
-	if ka.version >= VersionTLS12 {
-		signatureAlgorithm := SignatureScheme(sig[0])<<8 | SignatureScheme(sig[1])
-		sig = sig[2:]
-		if len(sig) < 2 {
-			return errServerKeyExchange
-		}
-
-		if !isSupportedSignatureAlgorithm(signatureAlgorithm, clientHello.supportedSignatureAlgorithms) {
-			return errors.New("tls: certificate used with invalid signature algorithm")
-		}
-		sigType, sigHash, err = typeAndHashFromSignatureScheme(signatureAlgorithm)
-		if err != nil {
-			return err
-		}
-	} else {
-		sigType, sigHash, err = legacyTypeAndHashFromPublicKey(cert.PublicKey)
-		if err != nil {
-			return err
-		}
-	}
-	if (sigType == signaturePKCS1v15 || sigType == signatureRSAPSS) != ka.isRSA {
-		return errServerKeyExchange
-	}
-
-	sigLen := int(sig[0])<<8 | int(sig[1])
-	if sigLen+2 != len(sig) {
-		return errServerKeyExchange
-	}
-	sig = sig[2:]
-
-	signed := hashForServerKeyExchange(sigType, sigHash, ka.version, clientHello.random, serverHello.random, serverECDHEParams)
-	if err := verifyHandshakeSignature(sigType, cert.PublicKey, sigHash, signed, sig); err != nil {
-		return errors.New("tls: invalid signature by the server certificate: " + err.Error())
-	}
-	return nil
-}
-
-func (ka *ecdheKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
-	if ka.ckx == nil {
-		return nil, nil, errors.New("tls: missing ServerKeyExchange message")
-	}
-
-	return ka.preMasterSecret, ka.ckx, nil
-}

+ 0 - 199
transport/cloudflaretls/key_schedule.go

@@ -1,199 +0,0 @@
-// Copyright 2018 The Go Authors. 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 (
-	"crypto/elliptic"
-	"crypto/hmac"
-	"errors"
-	"hash"
-	"io"
-	"math/big"
-
-	"golang.org/x/crypto/cryptobyte"
-	"golang.org/x/crypto/curve25519"
-	"golang.org/x/crypto/hkdf"
-)
-
-// This file contains the functions necessary to compute the TLS 1.3 key
-// schedule. See RFC 8446, Section 7.
-
-const (
-	resumptionBinderLabel         = "res binder"
-	clientHandshakeTrafficLabel   = "c hs traffic"
-	serverHandshakeTrafficLabel   = "s hs traffic"
-	clientApplicationTrafficLabel = "c ap traffic"
-	serverApplicationTrafficLabel = "s ap traffic"
-	exporterLabel                 = "exp master"
-	resumptionLabel               = "res master"
-	trafficUpdateLabel            = "traffic upd"
-)
-
-// expandLabel implements HKDF-Expand-Label from RFC 8446, Section 7.1.
-func (c *cipherSuiteTLS13) expandLabel(secret []byte, label string, context []byte, length int) []byte {
-	var hkdfLabel cryptobyte.Builder
-	hkdfLabel.AddUint16(uint16(length))
-	hkdfLabel.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
-		b.AddBytes([]byte("tls13 "))
-		b.AddBytes([]byte(label))
-	})
-	hkdfLabel.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
-		b.AddBytes(context)
-	})
-	out := make([]byte, length)
-	n, err := hkdf.Expand(c.hash.New, secret, hkdfLabel.BytesOrPanic()).Read(out)
-	if err != nil || n != length {
-		panic("tls: HKDF-Expand-Label invocation failed unexpectedly")
-	}
-	return out
-}
-
-// deriveSecret implements Derive-Secret from RFC 8446, Section 7.1.
-func (c *cipherSuiteTLS13) deriveSecret(secret []byte, label string, transcript hash.Hash) []byte {
-	if transcript == nil {
-		transcript = c.hash.New()
-	}
-	return c.expandLabel(secret, label, transcript.Sum(nil), c.hash.Size())
-}
-
-// extract implements HKDF-Extract with the cipher suite hash.
-func (c *cipherSuiteTLS13) extract(newSecret, currentSecret []byte) []byte {
-	if newSecret == nil {
-		newSecret = make([]byte, c.hash.Size())
-	}
-	return hkdf.Extract(c.hash.New, newSecret, currentSecret)
-}
-
-// nextTrafficSecret generates the next traffic secret, given the current one,
-// according to RFC 8446, Section 7.2.
-func (c *cipherSuiteTLS13) nextTrafficSecret(trafficSecret []byte) []byte {
-	return c.expandLabel(trafficSecret, trafficUpdateLabel, nil, c.hash.Size())
-}
-
-// trafficKey generates traffic keys according to RFC 8446, Section 7.3.
-func (c *cipherSuiteTLS13) trafficKey(trafficSecret []byte) (key, iv []byte) {
-	key = c.expandLabel(trafficSecret, "key", nil, c.keyLen)
-	iv = c.expandLabel(trafficSecret, "iv", nil, aeadNonceLength)
-	return
-}
-
-// finishedHash generates the Finished verify_data or PskBinderEntry according
-// to RFC 8446, Section 4.4.4. See sections 4.4 and 4.2.11.2 for the baseKey
-// selection.
-func (c *cipherSuiteTLS13) finishedHash(baseKey []byte, transcript hash.Hash) []byte {
-	finishedKey := c.expandLabel(baseKey, "finished", nil, c.hash.Size())
-	verifyData := hmac.New(c.hash.New, finishedKey)
-	verifyData.Write(transcript.Sum(nil))
-	return verifyData.Sum(nil)
-}
-
-// exportKeyingMaterial implements RFC5705 exporters for TLS 1.3 according to
-// RFC 8446, Section 7.5.
-func (c *cipherSuiteTLS13) exportKeyingMaterial(masterSecret []byte, transcript hash.Hash) func(string, []byte, int) ([]byte, error) {
-	expMasterSecret := c.deriveSecret(masterSecret, exporterLabel, transcript)
-	return func(label string, context []byte, length int) ([]byte, error) {
-		secret := c.deriveSecret(expMasterSecret, label, nil)
-		h := c.hash.New()
-		h.Write(context)
-		return c.expandLabel(secret, "exporter", h.Sum(nil), length), nil
-	}
-}
-
-// ecdheParameters implements Diffie-Hellman with either NIST curves or X25519,
-// according to RFC 8446, Section 4.2.8.2.
-type ecdheParameters interface {
-	CurveID() CurveID
-	PublicKey() []byte
-	SharedKey(peerPublicKey []byte) []byte
-}
-
-func generateECDHEParameters(rand io.Reader, curveID CurveID) (ecdheParameters, error) {
-	if curveID == X25519 {
-		privateKey := make([]byte, curve25519.ScalarSize)
-		if _, err := io.ReadFull(rand, privateKey); err != nil {
-			return nil, err
-		}
-		publicKey, err := curve25519.X25519(privateKey, curve25519.Basepoint)
-		if err != nil {
-			return nil, err
-		}
-		return &x25519Parameters{privateKey: privateKey, publicKey: publicKey}, nil
-	}
-
-	curve, ok := curveForCurveID(curveID)
-	if !ok {
-		return nil, errors.New("tls: internal error: unsupported curve")
-	}
-
-	p := &nistParameters{curveID: curveID}
-	var err error
-	p.privateKey, p.x, p.y, err = elliptic.GenerateKey(curve, rand)
-	if err != nil {
-		return nil, err
-	}
-	return p, nil
-}
-
-func curveForCurveID(id CurveID) (elliptic.Curve, bool) {
-	switch id {
-	case CurveP256:
-		return elliptic.P256(), true
-	case CurveP384:
-		return elliptic.P384(), true
-	case CurveP521:
-		return elliptic.P521(), true
-	default:
-		return nil, false
-	}
-}
-
-type nistParameters struct {
-	privateKey []byte
-	x, y       *big.Int // public key
-	curveID    CurveID
-}
-
-func (p *nistParameters) CurveID() CurveID {
-	return p.curveID
-}
-
-func (p *nistParameters) PublicKey() []byte {
-	curve, _ := curveForCurveID(p.curveID)
-	return elliptic.Marshal(curve, p.x, p.y)
-}
-
-func (p *nistParameters) SharedKey(peerPublicKey []byte) []byte {
-	curve, _ := curveForCurveID(p.curveID)
-	// Unmarshal also checks whether the given point is on the curve.
-	x, y := elliptic.Unmarshal(curve, peerPublicKey)
-	if x == nil {
-		return nil
-	}
-
-	xShared, _ := curve.ScalarMult(x, y, p.privateKey)
-	sharedKey := make([]byte, (curve.Params().BitSize+7)/8)
-	return xShared.FillBytes(sharedKey)
-}
-
-type x25519Parameters struct {
-	privateKey []byte
-	publicKey  []byte
-}
-
-func (p *x25519Parameters) CurveID() CurveID {
-	return X25519
-}
-
-func (p *x25519Parameters) PublicKey() []byte {
-	return p.publicKey[:]
-}
-
-func (p *x25519Parameters) SharedKey(peerPublicKey []byte) []byte {
-	sharedKey, err := curve25519.X25519(p.privateKey, peerPublicKey)
-	if err != nil {
-		return nil
-	}
-	return sharedKey
-}

+ 0 - 285
transport/cloudflaretls/prf.go

@@ -1,285 +0,0 @@
-// Copyright 2009 The Go Authors. 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 (
-	"crypto"
-	"crypto/hmac"
-	"crypto/md5"
-	"crypto/sha1"
-	"crypto/sha256"
-	"crypto/sha512"
-	"errors"
-	"fmt"
-	"hash"
-)
-
-// Split a premaster secret in two as specified in RFC 4346, Section 5.
-func splitPreMasterSecret(secret []byte) (s1, s2 []byte) {
-	s1 = secret[0 : (len(secret)+1)/2]
-	s2 = secret[len(secret)/2:]
-	return
-}
-
-// pHash implements the P_hash function, as defined in RFC 4346, Section 5.
-func pHash(result, secret, seed []byte, hash func() hash.Hash) {
-	h := hmac.New(hash, secret)
-	h.Write(seed)
-	a := h.Sum(nil)
-
-	j := 0
-	for j < len(result) {
-		h.Reset()
-		h.Write(a)
-		h.Write(seed)
-		b := h.Sum(nil)
-		copy(result[j:], b)
-		j += len(b)
-
-		h.Reset()
-		h.Write(a)
-		a = h.Sum(nil)
-	}
-}
-
-// prf10 implements the TLS 1.0 pseudo-random function, as defined in RFC 2246, Section 5.
-func prf10(result, secret, label, seed []byte) {
-	hashSHA1 := sha1.New
-	hashMD5 := md5.New
-
-	labelAndSeed := make([]byte, len(label)+len(seed))
-	copy(labelAndSeed, label)
-	copy(labelAndSeed[len(label):], seed)
-
-	s1, s2 := splitPreMasterSecret(secret)
-	pHash(result, s1, labelAndSeed, hashMD5)
-	result2 := make([]byte, len(result))
-	pHash(result2, s2, labelAndSeed, hashSHA1)
-
-	for i, b := range result2 {
-		result[i] ^= b
-	}
-}
-
-// prf12 implements the TLS 1.2 pseudo-random function, as defined in RFC 5246, Section 5.
-func prf12(hashFunc func() hash.Hash) func(result, secret, label, seed []byte) {
-	return func(result, secret, label, seed []byte) {
-		labelAndSeed := make([]byte, len(label)+len(seed))
-		copy(labelAndSeed, label)
-		copy(labelAndSeed[len(label):], seed)
-
-		pHash(result, secret, labelAndSeed, hashFunc)
-	}
-}
-
-const (
-	masterSecretLength   = 48 // Length of a master secret in TLS 1.1.
-	finishedVerifyLength = 12 // Length of verify_data in a Finished message.
-)
-
-var (
-	masterSecretLabel   = []byte("master secret")
-	keyExpansionLabel   = []byte("key expansion")
-	clientFinishedLabel = []byte("client finished")
-	serverFinishedLabel = []byte("server finished")
-)
-
-func prfAndHashForVersion(version uint16, suite *cipherSuite) (func(result, secret, label, seed []byte), crypto.Hash) {
-	switch version {
-	case VersionTLS10, VersionTLS11:
-		return prf10, crypto.Hash(0)
-	case VersionTLS12:
-		if suite.flags&suiteSHA384 != 0 {
-			return prf12(sha512.New384), crypto.SHA384
-		}
-		return prf12(sha256.New), crypto.SHA256
-	default:
-		panic("unknown version")
-	}
-}
-
-func prfForVersion(version uint16, suite *cipherSuite) func(result, secret, label, seed []byte) {
-	prf, _ := prfAndHashForVersion(version, suite)
-	return prf
-}
-
-// masterFromPreMasterSecret generates the master secret from the pre-master
-// secret. See RFC 5246, Section 8.1.
-func masterFromPreMasterSecret(version uint16, suite *cipherSuite, preMasterSecret, clientRandom, serverRandom []byte) []byte {
-	seed := make([]byte, 0, len(clientRandom)+len(serverRandom))
-	seed = append(seed, clientRandom...)
-	seed = append(seed, serverRandom...)
-
-	masterSecret := make([]byte, masterSecretLength)
-	prfForVersion(version, suite)(masterSecret, preMasterSecret, masterSecretLabel, seed)
-	return masterSecret
-}
-
-// keysFromMasterSecret generates the connection keys from the master
-// secret, given the lengths of the MAC key, cipher key and IV, as defined in
-// RFC 2246, Section 6.3.
-func keysFromMasterSecret(version uint16, suite *cipherSuite, masterSecret, clientRandom, serverRandom []byte, macLen, keyLen, ivLen int) (clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV []byte) {
-	seed := make([]byte, 0, len(serverRandom)+len(clientRandom))
-	seed = append(seed, serverRandom...)
-	seed = append(seed, clientRandom...)
-
-	n := 2*macLen + 2*keyLen + 2*ivLen
-	keyMaterial := make([]byte, n)
-	prfForVersion(version, suite)(keyMaterial, masterSecret, keyExpansionLabel, seed)
-	clientMAC = keyMaterial[:macLen]
-	keyMaterial = keyMaterial[macLen:]
-	serverMAC = keyMaterial[:macLen]
-	keyMaterial = keyMaterial[macLen:]
-	clientKey = keyMaterial[:keyLen]
-	keyMaterial = keyMaterial[keyLen:]
-	serverKey = keyMaterial[:keyLen]
-	keyMaterial = keyMaterial[keyLen:]
-	clientIV = keyMaterial[:ivLen]
-	keyMaterial = keyMaterial[ivLen:]
-	serverIV = keyMaterial[:ivLen]
-	return
-}
-
-func newFinishedHash(version uint16, cipherSuite *cipherSuite) finishedHash {
-	var buffer []byte
-	if version >= VersionTLS12 {
-		buffer = []byte{}
-	}
-
-	prf, hash := prfAndHashForVersion(version, cipherSuite)
-	if hash != 0 {
-		return finishedHash{hash.New(), hash.New(), nil, nil, buffer, version, prf}
-	}
-
-	return finishedHash{sha1.New(), sha1.New(), md5.New(), md5.New(), buffer, version, prf}
-}
-
-// A finishedHash calculates the hash of a set of handshake messages suitable
-// for including in a Finished message.
-type finishedHash struct {
-	client hash.Hash
-	server hash.Hash
-
-	// Prior to TLS 1.2, an additional MD5 hash is required.
-	clientMD5 hash.Hash
-	serverMD5 hash.Hash
-
-	// In TLS 1.2, a full buffer is sadly required.
-	buffer []byte
-
-	version uint16
-	prf     func(result, secret, label, seed []byte)
-}
-
-func (h *finishedHash) Write(msg []byte) (n int, err error) {
-	h.client.Write(msg)
-	h.server.Write(msg)
-
-	if h.version < VersionTLS12 {
-		h.clientMD5.Write(msg)
-		h.serverMD5.Write(msg)
-	}
-
-	if h.buffer != nil {
-		h.buffer = append(h.buffer, msg...)
-	}
-
-	return len(msg), nil
-}
-
-func (h finishedHash) Sum() []byte {
-	if h.version >= VersionTLS12 {
-		return h.client.Sum(nil)
-	}
-
-	out := make([]byte, 0, md5.Size+sha1.Size)
-	out = h.clientMD5.Sum(out)
-	return h.client.Sum(out)
-}
-
-// clientSum returns the contents of the verify_data member of a client's
-// Finished message.
-func (h finishedHash) clientSum(masterSecret []byte) []byte {
-	out := make([]byte, finishedVerifyLength)
-	h.prf(out, masterSecret, clientFinishedLabel, h.Sum())
-	return out
-}
-
-// serverSum returns the contents of the verify_data member of a server's
-// Finished message.
-func (h finishedHash) serverSum(masterSecret []byte) []byte {
-	out := make([]byte, finishedVerifyLength)
-	h.prf(out, masterSecret, serverFinishedLabel, h.Sum())
-	return out
-}
-
-// hashForClientCertificate returns the handshake messages so far, pre-hashed if
-// necessary, suitable for signing by a TLS client certificate.
-func (h finishedHash) hashForClientCertificate(sigType uint8, hashAlg crypto.Hash, masterSecret []byte) []byte {
-	if (h.version >= VersionTLS12 || sigType == signatureEd25519 || circlSchemeBySigType(sigType) != nil) && h.buffer == nil {
-		panic("tls: handshake hash for a client certificate requested after discarding the handshake buffer")
-	}
-
-	if sigType == signatureEd25519 || circlSchemeBySigType(sigType) != nil {
-		return h.buffer
-	}
-
-	if h.version >= VersionTLS12 {
-		hash := hashAlg.New()
-		hash.Write(h.buffer)
-		return hash.Sum(nil)
-	}
-
-	if sigType == signatureECDSA {
-		return h.server.Sum(nil)
-	}
-
-	return h.Sum()
-}
-
-// discardHandshakeBuffer is called when there is no more need to
-// buffer the entirety of the handshake messages.
-func (h *finishedHash) discardHandshakeBuffer() {
-	h.buffer = nil
-}
-
-// noExportedKeyingMaterial is used as a value of
-// ConnectionState.ekm when renegotiation is enabled and thus
-// we wish to fail all key-material export requests.
-func noExportedKeyingMaterial(label string, context []byte, length int) ([]byte, error) {
-	return nil, errors.New("crypto/tls: ExportKeyingMaterial is unavailable when renegotiation is enabled")
-}
-
-// ekmFromMasterSecret generates exported keying material as defined in RFC 5705.
-func ekmFromMasterSecret(version uint16, suite *cipherSuite, masterSecret, clientRandom, serverRandom []byte) func(string, []byte, int) ([]byte, error) {
-	return func(label string, context []byte, length int) ([]byte, error) {
-		switch label {
-		case "client finished", "server finished", "master secret", "key expansion":
-			// These values are reserved and may not be used.
-			return nil, fmt.Errorf("crypto/tls: reserved ExportKeyingMaterial label: %s", label)
-		}
-
-		seedLen := len(serverRandom) + len(clientRandom)
-		if context != nil {
-			seedLen += 2 + len(context)
-		}
-		seed := make([]byte, 0, seedLen)
-
-		seed = append(seed, clientRandom...)
-		seed = append(seed, serverRandom...)
-
-		if context != nil {
-			if len(context) >= 1<<16 {
-				return nil, fmt.Errorf("crypto/tls: ExportKeyingMaterial context too long")
-			}
-			seed = append(seed, byte(len(context)>>8), byte(len(context)))
-			seed = append(seed, context...)
-		}
-
-		keyMaterial := make([]byte, length)
-		prfForVersion(version, suite)(keyMaterial, masterSecret, []byte(label), seed)
-		return keyMaterial, nil
-	}
-}

+ 0 - 185
transport/cloudflaretls/ticket.go

@@ -1,185 +0,0 @@
-// Copyright 2012 The Go Authors. 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 (
-	"bytes"
-	"crypto/aes"
-	"crypto/cipher"
-	"crypto/hmac"
-	"crypto/sha256"
-	"crypto/subtle"
-	"errors"
-	"io"
-
-	"golang.org/x/crypto/cryptobyte"
-)
-
-// sessionState contains the information that is serialized into a session
-// ticket in order to later resume a connection.
-type sessionState struct {
-	vers         uint16
-	cipherSuite  uint16
-	createdAt    uint64
-	masterSecret []byte // opaque master_secret<1..2^16-1>;
-	// struct { opaque certificate<1..2^24-1> } Certificate;
-	certificates [][]byte // Certificate certificate_list<0..2^24-1>;
-
-	// usedOldKey is true if the ticket from which this session came from
-	// was encrypted with an older key and thus should be refreshed.
-	usedOldKey bool
-}
-
-func (m *sessionState) marshal() []byte {
-	var b cryptobyte.Builder
-	b.AddUint16(m.vers)
-	b.AddUint16(m.cipherSuite)
-	addUint64(&b, m.createdAt)
-	b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-		b.AddBytes(m.masterSecret)
-	})
-	b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
-		for _, cert := range m.certificates {
-			b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
-				b.AddBytes(cert)
-			})
-		}
-	})
-	return b.BytesOrPanic()
-}
-
-func (m *sessionState) unmarshal(data []byte) bool {
-	*m = sessionState{usedOldKey: m.usedOldKey}
-	s := cryptobyte.String(data)
-	if ok := s.ReadUint16(&m.vers) &&
-		s.ReadUint16(&m.cipherSuite) &&
-		readUint64(&s, &m.createdAt) &&
-		readUint16LengthPrefixed(&s, &m.masterSecret) &&
-		len(m.masterSecret) != 0; !ok {
-		return false
-	}
-	var certList cryptobyte.String
-	if !s.ReadUint24LengthPrefixed(&certList) {
-		return false
-	}
-	for !certList.Empty() {
-		var cert []byte
-		if !readUint24LengthPrefixed(&certList, &cert) {
-			return false
-		}
-		m.certificates = append(m.certificates, cert)
-	}
-	return s.Empty()
-}
-
-// sessionStateTLS13 is the content of a TLS 1.3 session ticket. Its first
-// version (revision = 0) doesn't carry any of the information needed for 0-RTT
-// validation and the nonce is always empty.
-type sessionStateTLS13 struct {
-	// uint8 version  = 0x0304;
-	// uint8 revision = 0;
-	cipherSuite      uint16
-	createdAt        uint64
-	resumptionSecret []byte      // opaque resumption_master_secret<1..2^8-1>;
-	certificate      Certificate // CertificateEntry certificate_list<0..2^24-1>;
-}
-
-func (m *sessionStateTLS13) marshal() []byte {
-	var b cryptobyte.Builder
-	b.AddUint16(VersionTLS13)
-	b.AddUint8(0) // revision
-	b.AddUint16(m.cipherSuite)
-	addUint64(&b, m.createdAt)
-	b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
-		b.AddBytes(m.resumptionSecret)
-	})
-	marshalCertificate(&b, m.certificate)
-	return b.BytesOrPanic()
-}
-
-func (m *sessionStateTLS13) unmarshal(data []byte) bool {
-	*m = sessionStateTLS13{}
-	s := cryptobyte.String(data)
-	var version uint16
-	var revision uint8
-	return s.ReadUint16(&version) &&
-		version == VersionTLS13 &&
-		s.ReadUint8(&revision) &&
-		revision == 0 &&
-		s.ReadUint16(&m.cipherSuite) &&
-		readUint64(&s, &m.createdAt) &&
-		readUint8LengthPrefixed(&s, &m.resumptionSecret) &&
-		len(m.resumptionSecret) != 0 &&
-		unmarshalCertificate(&s, &m.certificate) &&
-		s.Empty()
-}
-
-func (c *Conn) encryptTicket(state []byte) ([]byte, error) {
-	if len(c.ticketKeys) == 0 {
-		return nil, errors.New("tls: internal error: session ticket keys unavailable")
-	}
-
-	encrypted := make([]byte, ticketKeyNameLen+aes.BlockSize+len(state)+sha256.Size)
-	keyName := encrypted[:ticketKeyNameLen]
-	iv := encrypted[ticketKeyNameLen : ticketKeyNameLen+aes.BlockSize]
-	macBytes := encrypted[len(encrypted)-sha256.Size:]
-
-	if _, err := io.ReadFull(c.config.rand(), iv); err != nil {
-		return nil, err
-	}
-	key := c.ticketKeys[0]
-	copy(keyName, key.keyName[:])
-	block, err := aes.NewCipher(key.aesKey[:])
-	if err != nil {
-		return nil, errors.New("tls: failed to create cipher while encrypting ticket: " + err.Error())
-	}
-	cipher.NewCTR(block, iv).XORKeyStream(encrypted[ticketKeyNameLen+aes.BlockSize:], state)
-
-	mac := hmac.New(sha256.New, key.hmacKey[:])
-	mac.Write(encrypted[:len(encrypted)-sha256.Size])
-	mac.Sum(macBytes[:0])
-
-	return encrypted, nil
-}
-
-func (c *Conn) decryptTicket(encrypted []byte) (plaintext []byte, usedOldKey bool) {
-	if len(encrypted) < ticketKeyNameLen+aes.BlockSize+sha256.Size {
-		return nil, false
-	}
-
-	keyName := encrypted[:ticketKeyNameLen]
-	iv := encrypted[ticketKeyNameLen : ticketKeyNameLen+aes.BlockSize]
-	macBytes := encrypted[len(encrypted)-sha256.Size:]
-	ciphertext := encrypted[ticketKeyNameLen+aes.BlockSize : len(encrypted)-sha256.Size]
-
-	keyIndex := -1
-	for i, candidateKey := range c.ticketKeys {
-		if bytes.Equal(keyName, candidateKey.keyName[:]) {
-			keyIndex = i
-			break
-		}
-	}
-	if keyIndex == -1 {
-		return nil, false
-	}
-	key := &c.ticketKeys[keyIndex]
-
-	mac := hmac.New(sha256.New, key.hmacKey[:])
-	mac.Write(encrypted[:len(encrypted)-sha256.Size])
-	expected := mac.Sum(nil)
-
-	if subtle.ConstantTimeCompare(macBytes, expected) != 1 {
-		return nil, false
-	}
-
-	block, err := aes.NewCipher(key.aesKey[:])
-	if err != nil {
-		return nil, false
-	}
-	plaintext = make([]byte, len(ciphertext))
-	cipher.NewCTR(block, iv).XORKeyStream(plaintext, ciphertext)
-
-	return plaintext, keyIndex > 0
-}

+ 0 - 410
transport/cloudflaretls/tls.go

@@ -1,410 +0,0 @@
-// Copyright 2009 The Go Authors. 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 partially implements TLS 1.2, as specified in RFC 5246,
-// and TLS 1.3, as specified in RFC 8446.
-//
-// This package implements the "Encrypted ClientHello (ECH)" extension, as
-// specified by draft-ietf-tls-esni-13. This extension allows the client to
-// encrypt its ClientHello to the public key of an ECH-service provider, known
-// as the client-facing server. If successful, then the client-facing server
-// forwards the decrypted ClientHello to the intended recipient, known as the
-// backend server. The goal of this mechanism is to ensure that connections made
-// to backend servers are indistinguishable from one another.
-//
-// This package implements the "Delegated Credentials" extension, as
-// specified by draft-ietf-tls-subcerts-10. This extension allows the usage
-// of a limited delegation mechanism that allows a TLS peer to issue its own
-// credentials within the scope of a certificate issued by an external
-// CA. These credentials only enable the recipient of the delegation to
-// speak for names that the CA has authorized. If the client or server supports
-// this extension, then the server or client may use a "delegated credential"
-// as the signing key in the handshake. A delegated credential is a short lived
-// public/secret key pair delegated to the peer by an entity trusted by the
-// corresponding peer. This allows a reverse proxy to terminate a TLS connection
-// on behalf of the entity. Credentials can't be revoked; in order to
-// mitigate risk in case the reverse proxy is compromised, the credential is only
-// valid for a short time (days, hours, or even minutes).
-package tls
-
-// BUG(cjpatton): In order to achieve its security goal, the ECH extension
-// requires padding in order to ensure that the length of handshake messages
-// doesn't depend on who terminates the connection. This package does not yet
-// implement server-side padding: see
-// https://github.com/tlswg/draft-ietf-tls-esni/issues/264.
-
-// BUG(cjpatton): The interaction of the ECH extension with PSK has not yet been
-// fully vetted. For now, the server disables session tickets if ECH is enabled.
-
-// BUG(cjpatton): Upon ECH rejection, if retry configurations are provided, then
-// the client is expected to retry the connection. Otherwise, it may regard ECH
-// as being securely disabled by the client-facing server. The client in this
-// package does not attempt to retry the handshake.
-
-// BUG(cjpatton): If the client offers the ECH extension and the client-facing
-// server rejects it, then only the client-facing server is authenticated. In
-// particular, the client is expected to respond to a CertificateRequest with an
-// empty certificate. This package does not yet implement this behavior.
-
-// BUG(agl): The crypto/tls package only implements some countermeasures
-// against Lucky13 attacks on CBC-mode encryption, and only on SHA1
-// variants. See http://www.isg.rhul.ac.uk/tls/TLStiming.pdf and
-// https://www.imperialviolet.org/2013/02/04/luckythirteen.html.
-
-import (
-	"bytes"
-	"context"
-	"crypto"
-	"crypto/ecdsa"
-	"crypto/ed25519"
-	"crypto/rsa"
-	"crypto/x509"
-	"encoding/pem"
-	"errors"
-	"fmt"
-	"net"
-	"os"
-	"strings"
-
-	circlSign "github.com/cloudflare/circl/sign"
-)
-
-// Server returns a new TLS server side connection
-// using conn as the underlying transport.
-// The configuration config must be non-nil and must include
-// at least one certificate or else set GetCertificate.
-func Server(conn net.Conn, config *Config) *Conn {
-	c := &Conn{
-		conn:   conn,
-		config: config,
-	}
-	c.handshakeFn = c.serverHandshake
-	return c
-}
-
-// Client returns a new TLS client side connection
-// using conn as the underlying transport.
-// The config cannot be nil: users must set either ServerName or
-// InsecureSkipVerify in the config.
-func Client(conn net.Conn, config *Config) *Conn {
-	c := &Conn{
-		conn:     conn,
-		config:   config,
-		isClient: true,
-	}
-	c.handshakeFn = c.clientHandshake
-	return c
-}
-
-// A listener implements a network listener (net.Listener) for TLS connections.
-type listener struct {
-	net.Listener
-	config *Config
-}
-
-// Accept waits for and returns the next incoming TLS connection.
-// The returned connection is of type *Conn.
-func (l *listener) Accept() (net.Conn, error) {
-	c, err := l.Listener.Accept()
-	if err != nil {
-		return nil, err
-	}
-	return Server(c, l.config), nil
-}
-
-// NewListener creates a Listener which accepts connections from an inner
-// Listener and wraps each connection with Server.
-// The configuration config must be non-nil and must include
-// at least one certificate or else set GetCertificate.
-func NewListener(inner net.Listener, config *Config) net.Listener {
-	l := new(listener)
-	l.Listener = inner
-	l.config = config
-	return l
-}
-
-// Listen creates a TLS listener accepting connections on the
-// given network address using net.Listen.
-// The configuration config must be non-nil and must include
-// at least one certificate or else set GetCertificate.
-func Listen(network, laddr string, config *Config) (net.Listener, error) {
-	if config == nil || len(config.Certificates) == 0 &&
-		config.GetCertificate == nil && config.GetConfigForClient == nil {
-		return nil, errors.New("tls: neither Certificates, GetCertificate, nor GetConfigForClient set in Config")
-	}
-	l, err := net.Listen(network, laddr)
-	if err != nil {
-		return nil, err
-	}
-	return NewListener(l, config), nil
-}
-
-type timeoutError struct{}
-
-func (timeoutError) Error() string   { return "tls: DialWithDialer timed out" }
-func (timeoutError) Timeout() bool   { return true }
-func (timeoutError) Temporary() bool { return true }
-
-// DialWithDialer connects to the given network address using dialer.Dial and
-// then initiates a TLS handshake, returning the resulting TLS connection. Any
-// timeout or deadline given in the dialer apply to connection and TLS
-// handshake as a whole.
-//
-// DialWithDialer interprets a nil configuration as equivalent to the zero
-// configuration; see the documentation of Config for the defaults.
-//
-// DialWithDialer uses context.Background internally; to specify the context,
-// use Dialer.DialContext with NetDialer set to the desired dialer.
-func DialWithDialer(dialer *net.Dialer, network, addr string, config *Config) (*Conn, error) {
-	return dial(context.Background(), dialer, network, addr, config)
-}
-
-func dial(ctx context.Context, netDialer *net.Dialer, network, addr string, config *Config) (*Conn, error) {
-	if netDialer.Timeout != 0 {
-		var cancel context.CancelFunc
-		ctx, cancel = context.WithTimeout(ctx, netDialer.Timeout)
-		defer cancel()
-	}
-
-	if !netDialer.Deadline.IsZero() {
-		var cancel context.CancelFunc
-		ctx, cancel = context.WithDeadline(ctx, netDialer.Deadline)
-		defer cancel()
-	}
-
-	rawConn, err := netDialer.DialContext(ctx, network, addr)
-	if err != nil {
-		return nil, err
-	}
-
-	colonPos := strings.LastIndex(addr, ":")
-	if colonPos == -1 {
-		colonPos = len(addr)
-	}
-	hostname := addr[:colonPos]
-
-	if config == nil {
-		config = defaultConfig()
-	}
-	// If no ServerName is set, infer the ServerName
-	// from the hostname we're connecting to.
-	if config.ServerName == "" {
-		// Make a copy to avoid polluting argument or default.
-		c := config.Clone()
-		c.ServerName = hostname
-		config = c
-	}
-
-	conn := Client(rawConn, config)
-	if err := conn.HandshakeContext(ctx); err != nil {
-		rawConn.Close()
-		return nil, err
-	}
-	return conn, nil
-}
-
-// Dial connects to the given network address using net.Dial
-// and then initiates a TLS handshake, returning the resulting
-// TLS connection.
-// Dial interprets a nil configuration as equivalent to
-// the zero configuration; see the documentation of Config
-// for the defaults.
-func Dial(network, addr string, config *Config) (*Conn, error) {
-	return DialWithDialer(new(net.Dialer), network, addr, config)
-}
-
-// Dialer dials TLS connections given a configuration and a Dialer for the
-// underlying connection.
-type Dialer struct {
-	// NetDialer is the optional dialer to use for the TLS connections'
-	// underlying TCP connections.
-	// A nil NetDialer is equivalent to the net.Dialer zero value.
-	NetDialer *net.Dialer
-
-	// Config is the TLS configuration to use for new connections.
-	// A nil configuration is equivalent to the zero
-	// configuration; see the documentation of Config for the
-	// defaults.
-	Config *Config
-}
-
-// Dial connects to the given network address and initiates a TLS
-// handshake, returning the resulting TLS connection.
-//
-// The returned Conn, if any, will always be of type *Conn.
-//
-// Dial uses context.Background internally; to specify the context,
-// use DialContext.
-func (d *Dialer) Dial(network, addr string) (net.Conn, error) {
-	return d.DialContext(context.Background(), network, addr)
-}
-
-func (d *Dialer) netDialer() *net.Dialer {
-	if d.NetDialer != nil {
-		return d.NetDialer
-	}
-	return new(net.Dialer)
-}
-
-// DialContext connects to the given network address and initiates a TLS
-// handshake, returning the resulting TLS connection.
-//
-// The provided Context must be non-nil. If the context expires before
-// the connection is complete, an error is returned. Once successfully
-// connected, any expiration of the context will not affect the
-// connection.
-//
-// The returned Conn, if any, will always be of type *Conn.
-func (d *Dialer) DialContext(ctx context.Context, network, addr string) (net.Conn, error) {
-	c, err := dial(ctx, d.netDialer(), network, addr, d.Config)
-	if err != nil {
-		// Don't return c (a typed nil) in an interface.
-		return nil, err
-	}
-	return c, nil
-}
-
-// LoadX509KeyPair reads and parses a public/private key pair from a pair
-// of files. The files must contain PEM encoded data. The certificate file
-// may contain intermediate certificates following the leaf certificate to
-// form a certificate chain. On successful return, Certificate.Leaf will
-// be nil because the parsed form of the certificate is not retained.
-func LoadX509KeyPair(certFile, keyFile string) (Certificate, error) {
-	certPEMBlock, err := os.ReadFile(certFile)
-	if err != nil {
-		return Certificate{}, err
-	}
-	keyPEMBlock, err := os.ReadFile(keyFile)
-	if err != nil {
-		return Certificate{}, err
-	}
-	return X509KeyPair(certPEMBlock, keyPEMBlock)
-}
-
-// X509KeyPair parses a public/private key pair from a pair of
-// PEM encoded data. On successful return, Certificate.Leaf will be nil because
-// the parsed form of the certificate is not retained.
-func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (Certificate, error) {
-	fail := func(err error) (Certificate, error) { return Certificate{}, err }
-
-	var cert Certificate
-	var skippedBlockTypes []string
-	for {
-		var certDERBlock *pem.Block
-		certDERBlock, certPEMBlock = pem.Decode(certPEMBlock)
-		if certDERBlock == nil {
-			break
-		}
-		if certDERBlock.Type == "CERTIFICATE" {
-			cert.Certificate = append(cert.Certificate, certDERBlock.Bytes)
-		} else {
-			skippedBlockTypes = append(skippedBlockTypes, certDERBlock.Type)
-		}
-	}
-
-	if len(cert.Certificate) == 0 {
-		if len(skippedBlockTypes) == 0 {
-			return fail(errors.New("tls: failed to find any PEM data in certificate input"))
-		}
-		if len(skippedBlockTypes) == 1 && strings.HasSuffix(skippedBlockTypes[0], "PRIVATE KEY") {
-			return fail(errors.New("tls: failed to find certificate PEM data in certificate input, but did find a private key; PEM inputs may have been switched"))
-		}
-		return fail(fmt.Errorf("tls: failed to find \"CERTIFICATE\" PEM block in certificate input after skipping PEM blocks of the following types: %v", skippedBlockTypes))
-	}
-
-	skippedBlockTypes = skippedBlockTypes[:0]
-	var keyDERBlock *pem.Block
-	for {
-		keyDERBlock, keyPEMBlock = pem.Decode(keyPEMBlock)
-		if keyDERBlock == nil {
-			if len(skippedBlockTypes) == 0 {
-				return fail(errors.New("tls: failed to find any PEM data in key input"))
-			}
-			if len(skippedBlockTypes) == 1 && skippedBlockTypes[0] == "CERTIFICATE" {
-				return fail(errors.New("tls: found a certificate rather than a key in the PEM for the private key"))
-			}
-			return fail(fmt.Errorf("tls: failed to find PEM block with type ending in \"PRIVATE KEY\" in key input after skipping PEM blocks of the following types: %v", skippedBlockTypes))
-		}
-		if keyDERBlock.Type == "PRIVATE KEY" || strings.HasSuffix(keyDERBlock.Type, " PRIVATE KEY") {
-			break
-		}
-		skippedBlockTypes = append(skippedBlockTypes, keyDERBlock.Type)
-	}
-
-	// We don't need to parse the public key for TLS, but we so do anyway
-	// to check that it looks sane and matches the private key.
-	x509Cert, err := x509.ParseCertificate(cert.Certificate[0])
-	if err != nil {
-		return fail(err)
-	}
-
-	cert.PrivateKey, err = parsePrivateKey(keyDERBlock.Bytes)
-	if err != nil {
-		return fail(err)
-	}
-
-	switch pub := x509Cert.PublicKey.(type) {
-	case *rsa.PublicKey:
-		priv, ok := cert.PrivateKey.(*rsa.PrivateKey)
-		if !ok {
-			return fail(errors.New("tls: private key type does not match public key type"))
-		}
-		if pub.N.Cmp(priv.N) != 0 {
-			return fail(errors.New("tls: private key does not match public key"))
-		}
-	case *ecdsa.PublicKey:
-		priv, ok := cert.PrivateKey.(*ecdsa.PrivateKey)
-		if !ok {
-			return fail(errors.New("tls: private key type does not match public key type"))
-		}
-		if pub.X.Cmp(priv.X) != 0 || pub.Y.Cmp(priv.Y) != 0 {
-			return fail(errors.New("tls: private key does not match public key"))
-		}
-	case ed25519.PublicKey:
-		priv, ok := cert.PrivateKey.(ed25519.PrivateKey)
-		if !ok {
-			return fail(errors.New("tls: private key type does not match public key type"))
-		}
-		if !bytes.Equal(priv.Public().(ed25519.PublicKey), pub) {
-			return fail(errors.New("tls: private key does not match public key"))
-		}
-	case circlSign.PublicKey:
-		priv, ok := cert.PrivateKey.(circlSign.PrivateKey)
-		if !ok {
-			return fail(errors.New("tls: private key type does not match public key type"))
-		}
-		pkBytes, err := priv.Public().(circlSign.PublicKey).MarshalBinary()
-		pkBytes2, err2 := pub.MarshalBinary()
-
-		if err != nil || err2 != nil || !bytes.Equal(pkBytes, pkBytes2) {
-			return fail(errors.New("tls: private key does not match public key"))
-		}
-	default:
-		return fail(errors.New("tls: unknown public key algorithm"))
-	}
-
-	return cert, nil
-}
-
-// Attempt to parse the given private key DER block. OpenSSL 0.9.8 generates
-// PKCS #1 private keys by default, while OpenSSL 1.0.0 generates PKCS #8 keys.
-// OpenSSL ecparam generates SEC1 EC private keys for ECDSA. We try all three.
-func parsePrivateKey(der []byte) (crypto.PrivateKey, error) {
-	if key, err := x509.ParsePKCS1PrivateKey(der); err == nil {
-		return key, nil
-	}
-	if key, err := x509.ParsePKCS8PrivateKey(der); err == nil {
-		switch key := key.(type) {
-		case *rsa.PrivateKey, *ecdsa.PrivateKey, ed25519.PrivateKey, circlSign.PrivateKey:
-			return key, nil
-		default:
-			return nil, errors.New("tls: found unknown private key type in PKCS#8 wrapping")
-		}
-	}
-	if key, err := x509.ParseECPrivateKey(der); err == nil {
-		return key, nil
-	}
-
-	return nil, errors.New("tls: failed to parse private key")
-}

+ 0 - 241
transport/cloudflaretls/tls_cf.go

@@ -1,241 +0,0 @@
-// 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"
-}