From 09b6257de0a076c1d15dbfc246e111c2ee26827d Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Sat, 23 Nov 2019 00:45:31 +0100 Subject: [PATCH] [sans-io] tls tests++ --- .../data/verificationcerts/9da13359.0 | 21 ++++ .../data/verificationcerts/generate.py | 75 ++++++++++++++ .../openssl-trusted-leaf.conf | 5 + .../data/verificationcerts/self-signed.crt | 22 +++++ .../data/verificationcerts/self-signed.key | 27 +++++ .../data/verificationcerts/trusted-leaf.crt | 21 ++++ .../data/verificationcerts/trusted-leaf.key | 27 +++++ .../data/verificationcerts/trusted-root.crt | 21 ++++ .../data/verificationcerts/trusted-root.key | 27 +++++ .../data/verificationcerts/trusted-root.srl | 1 + test/mitmproxy/proxy2/layers/test_tls.py | 98 +++++++++++++++---- 11 files changed, 328 insertions(+), 17 deletions(-) create mode 100644 test/mitmproxy/data/verificationcerts/9da13359.0 create mode 100644 test/mitmproxy/data/verificationcerts/generate.py create mode 100644 test/mitmproxy/data/verificationcerts/openssl-trusted-leaf.conf create mode 100644 test/mitmproxy/data/verificationcerts/self-signed.crt create mode 100644 test/mitmproxy/data/verificationcerts/self-signed.key create mode 100644 test/mitmproxy/data/verificationcerts/trusted-leaf.crt create mode 100644 test/mitmproxy/data/verificationcerts/trusted-leaf.key create mode 100644 test/mitmproxy/data/verificationcerts/trusted-root.crt create mode 100644 test/mitmproxy/data/verificationcerts/trusted-root.key create mode 100644 test/mitmproxy/data/verificationcerts/trusted-root.srl diff --git a/test/mitmproxy/data/verificationcerts/9da13359.0 b/test/mitmproxy/data/verificationcerts/9da13359.0 new file mode 100644 index 000000000..0182d8cfd --- /dev/null +++ b/test/mitmproxy/data/verificationcerts/9da13359.0 @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDazCCAlOgAwIBAgIUT0IDh7/Cho/ZPuVDs/jg7g/6+lswDQYJKoZIhvcNAQEL +BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0xOTExMjIyMjQxNDdaFw0zOTEx +MTcyMjQxNDdaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw +HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQCvx49WJyThnCZ/qQuotMpe1ZvokAfDmpS399815yn7 +kf2zsbuvb/nFGY6Y+tiaLOQkRqB7pV5fuolBng9Z5NDhu8Qw2WXAFDXQxpSsJVLx +lKyzt98RU8qoOuL9SipX2DjRMkBsm0FInCWeACWDWkn0DIPfW71FddtOIN2Q/kBE +LdpP9mZ4/RfJw6CpZXNvbwnTqwqOvpzpkaQDmbKFJwGFsKYyOctwEcE8qtR0YKs3 +5dCS/FTs6kc41V3ioaMBj2HaXwq+6R0I/939wrtwDKxFpH5NwES8T4oeSvnuszlk +o7Ot0IK4uCz8R+FCLZuRU9U+yP0KOdMRTZ9OBVMoLzxZAgMBAAGjUzBRMB0GA1Ud +DgQWBBTQj9qqsEovqpBmFZlWVSJRBYxeRTAfBgNVHSMEGDAWgBTQj9qqsEovqpBm +FZlWVSJRBYxeRTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQA9 +0R1JZJ/075J8ZJFvuYZURjD9D3NZdcp80X503UBXmNgkePVKOTlVlxStuuF87EY4 +BkUoqR+QE9xxr9uAyTX1xGMDEDCso0ylPmsT+p/uXdWzijNNQywg+X7/UprF20o+ +TPJNah+fQgcunvb3bjviOsIgSBFE8N9sNZLNTn1vc5mvKfzrT0svj5y31HwbOHmZ +85nyupjrrXzgDZBCIQLQpepfkjjOxm82oD3eszzNWe1x+ukvqKFWVQtUbP3hlclT +bgZuy/1NG4oZXgqGysNn0zxx4xixxbJhKb140TtH5xwAC08X3m5sTkcmDVjqJKWG +jemUYIi4o/YRxDEMChXT +-----END CERTIFICATE----- diff --git a/test/mitmproxy/data/verificationcerts/generate.py b/test/mitmproxy/data/verificationcerts/generate.py new file mode 100644 index 000000000..50a99d449 --- /dev/null +++ b/test/mitmproxy/data/verificationcerts/generate.py @@ -0,0 +1,75 @@ +""" +Generate SSL test certificates. +""" +import subprocess +import shlex +import os +import shutil +import textwrap + +ROOT_CA = "trusted-root" +SUBJECT = "example.mitmproxy.org" + + +def do(args): + print("> %s" % args) + args = shlex.split(args) + output = subprocess.check_output(args) + return output + + +def genrsa(cert: str): + do(f"openssl genrsa -out {cert}.key 2048") + + +def sign(cert: str, subject: str): + with open(f"openssl-{cert}.conf", "w") as f: + f.write(textwrap.dedent(f""" + authorityKeyIdentifier=keyid,issuer + basicConstraints=CA:FALSE + keyUsage = digitalSignature, keyEncipherment + subjectAltName = {subject} + """)) + do(f"openssl x509 -req -in {cert}.csr " + f"-CA {ROOT_CA}.crt " + f"-CAkey {ROOT_CA}.key " + f"-CAcreateserial " + f"-days 7300 " + f"-sha256 " + f"-extfile \"openssl-{cert}.conf\" " + f"-out {cert}.crt" + ) + + +def mkcert(cert, subject): + genrsa(cert) + do(f"openssl req -new -nodes -batch " + f"-key {cert}.key " + f"-addext \"subjectAltName = {subject}\" " + f"-out {cert}.csr" + ) + sign(cert, subject) + os.remove(f"{cert}.csr") + + +# create trusted root CA +genrsa("trusted-root") +do("openssl req -x509 -new -nodes -batch " + "-key trusted-root.key " + "-days 7300 " + "-out trusted-root.crt" + ) +h = do("openssl x509 -hash -noout -in trusted-root.crt").decode("ascii").strip() +shutil.copyfile("trusted-root.crt", "{}.0".format(h)) + +# create trusted leaf cert. +mkcert("trusted-leaf", f'DNS:{SUBJECT}' ) + +# create self-signed cert +genrsa("self-signed") +do("openssl req -x509 -new -nodes -batch " + "-key self-signed.key " + f'-addext "subjectAltName = DNS:{SUBJECT}" ' + "-days 7300 " + "-out self-signed.crt" + ) diff --git a/test/mitmproxy/data/verificationcerts/openssl-trusted-leaf.conf b/test/mitmproxy/data/verificationcerts/openssl-trusted-leaf.conf new file mode 100644 index 000000000..18f9e78d6 --- /dev/null +++ b/test/mitmproxy/data/verificationcerts/openssl-trusted-leaf.conf @@ -0,0 +1,5 @@ + +authorityKeyIdentifier=keyid,issuer +basicConstraints=CA:FALSE +keyUsage = digitalSignature, keyEncipherment +subjectAltName = DNS:example.mitmproxy.org diff --git a/test/mitmproxy/data/verificationcerts/self-signed.crt b/test/mitmproxy/data/verificationcerts/self-signed.crt new file mode 100644 index 000000000..1d6c4bd01 --- /dev/null +++ b/test/mitmproxy/data/verificationcerts/self-signed.crt @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDjTCCAnWgAwIBAgIUaT2PYFnhh/rd5w6CdEPpM/aX7ngwDQYJKoZIhvcNAQEL +BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0xOTExMjIyMjQxNDdaFw0zOTEx +MTcyMjQxNDdaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw +HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQDJQZUdzP2zhaNnPJr3F4tcr7Mv2JaWql1mtgRDizCi +TC4UCjeG/JPxqXvnUl9U6QgeGMVnFLIYrZIcCQl/qrVHqkgFPc6Vw7nP7MCYUY+P +div2K0S1vh+NgoBkMfgm2zMyeRjwL2P3qFRljePub3oLfEGMnw05MZHISuhxv9Nn +8lT2+V2sXK3XyEe1vDa8hoZ8SlRYSDqlYr/+HGygIjNpHjUcgQNrYeVYc2Ty31Iu +dipYRr9ivZxSLEDjxi5OKef+lCiJ3xdmykqJmmW0GQPhi6VljCQFK8LLRr+hlrdG +sP0SC4H3iMEpdcyLrm+vSgYxdIoSfhunfkUSuRP/PHgFAgMBAAGjdTBzMB0GA1Ud +DgQWBBSTLOIeV9/IwnAL12yoDrlS7bQudDAfBgNVHSMEGDAWgBSTLOIeV9/IwnAL +12yoDrlS7bQudDAPBgNVHRMBAf8EBTADAQH/MCAGA1UdEQQZMBeCFWV4YW1wbGUu +bWl0bXByb3h5Lm9yZzANBgkqhkiG9w0BAQsFAAOCAQEArCOkLh0OBhEJz9FNWvs5 +yvWjk4d+I/pNnQmVbWg3TvoxbFp/3CJW3tAkZ6mwI6DqLEcIeekh8THCFhk3XbFd +GHsCA4mX2qQWmaLrWEqV+Z2Ai/GffJ0+fh7RLHSvPHK4I5/4Phv0yjuUqu+mFv9B +BT4IImQp1Tknzsew3PhtpV2zscCnnjokFhKMtPQiULbuS9BzikVtX4dGN9yWUSe2 +nxKLTfFlr3K8a3CypLPXMQM8iZ76SY4ZSFBHuiRM9cq9MNmkpwRN1zSD4IkTczAR +sxkKnKvgu0xRkJHzxfLEy/v1NDFE5K+tF6kNYtyswo4SmFniguZNpXQD/7fQlyoO +RA== +-----END CERTIFICATE----- diff --git a/test/mitmproxy/data/verificationcerts/self-signed.key b/test/mitmproxy/data/verificationcerts/self-signed.key new file mode 100644 index 000000000..f61a64606 --- /dev/null +++ b/test/mitmproxy/data/verificationcerts/self-signed.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAyUGVHcz9s4WjZzya9xeLXK+zL9iWlqpdZrYEQ4swokwuFAo3 +hvyT8al751JfVOkIHhjFZxSyGK2SHAkJf6q1R6pIBT3OlcO5z+zAmFGPj3Yr9itE +tb4fjYKAZDH4JtszMnkY8C9j96hUZY3j7m96C3xBjJ8NOTGRyErocb/TZ/JU9vld +rFyt18hHtbw2vIaGfEpUWEg6pWK//hxsoCIzaR41HIEDa2HlWHNk8t9SLnYqWEa/ +Yr2cUixA48YuTinn/pQoid8XZspKiZpltBkD4YulZYwkBSvCy0a/oZa3RrD9EguB +94jBKXXMi65vr0oGMXSKEn4bp35FErkT/zx4BQIDAQABAoIBAQCanNOeLVnKjSRX +r2ut4FykPCcA3vfxj7hpq/PioBAg3z2XD7JQ9cICqh4SPGoYpV4jIQymgHPCGbZh +619swQy7ncnunOkUjWU2o7/iROZxZGupltwWc5Vx9YwFbY4i68uNPxM1knLOVHdh +/XvaNbIhGLiS+64A/l/s6/9fQ+t5sojGRg1FYpiEam1U9BEGBs/gSKWj7uThR1Xi +feU0LFKRVuOBWtbQuoR9EnookQkyVnmtMuR0fYxuC0qFDV1UQKn0NI6PW7oldpbB +oLJn+mREK5yoWIgyO6uDT2X3OE9c3W1chrFDUSnIqeHpDFsC2KTZtOf1F7ZuP/hW +JXNedSOBAoGBAPEcBsTeinErezB/ZDkQoFT8gjHFfE7LFUZHuy7vQjfyG9kSEJn7 +iR7AMxGSb4WD2Clz87Cdm54c6hq/9kBShuePxAa502kGAcumsVg4xAWFY5oSatyd +Y6Yyvj+k11H1top2sd3fd523UmOUHs/HmlQYN86oqTX0Rd+qMLSoMsN5AoGBANWv +eFMQ+r3Tw1mPNzH93Sx66xEUVFO9mp+X+ZkKatbY5AfWoAsrn/bcJXEynkjBJ2O9 +BxXPbycCT9/jn+s1ba7z3+vGG9zoB7TX2VnpA1/J158veHzHnfteNUS/mUS1M8AG +fijk0nMklutXhtFaEkxK73psAm/91HCaozYigEntAoGAVBRX7/NDB/AHx4PFKXk4 +0Co2JLEfhkKfqqB9EALzbpsJRwtbqrbivEx+ApS0OzUc/menBWIQ0HR41tc2QnwE ++19RFp9ar/ceTSxWD9PL17kKYMInbcOc6mormfob9ELhYyu9Hwg8qE0zd/JBRGfw +036Wh4SdbWk/rJ2m2nkFKtECgYEAuh1H5smeKuIbfpDPmTosfoZc4RZc0EcPOrvK +iLJbFd/41J7p7HDFteROtEZLOMELRsKoPiXbARXxbea7LcjuTHha6uc083Yg6DEs +PTRHXRHXPO3CuqO+hOar7MIYg5Bzj2fYUFPkvKb8z+P/J66Uy2BlLrKOeO6TLrRx +PUBVjo0CgYAoA9aOVArgskbcDlCNJh0hlA+GtAOJMCR7Sk+JsXVY6XzjrPc2PAq0 +mE2aiN04nHNzQH8LYfwSa361I480FDc8ZmCIKSc58b5RU9+PWko93qaxPc8fRjyJ +GzpvHWJpxWkdocv6iywysyh2jsE+KlE7YBryLnp8hsUs+M8m7B3VRA== +-----END RSA PRIVATE KEY----- diff --git a/test/mitmproxy/data/verificationcerts/trusted-leaf.crt b/test/mitmproxy/data/verificationcerts/trusted-leaf.crt new file mode 100644 index 000000000..83b7c9088 --- /dev/null +++ b/test/mitmproxy/data/verificationcerts/trusted-leaf.crt @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDdTCCAl2gAwIBAgIUPoeu9ozif3OWwzCVA7tZWtlzLz8wDQYJKoZIhvcNAQEL +BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0xOTExMjIyMjQxNDdaFw0zOTEx +MTcyMjQxNDdaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw +HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQCZQxoIZMee+qy7FVOFG11Rv7b37/fX5M3SG/Z5ZVoX +Nvdz339ULaJTSaoTX2l/zQrMzu420TyfEXLkr/wZUaV9GfZli1gYn6Mu0TYOSY9h +saA98aHK5eAzD4PGR+HgumqN+SFXbcFlw6kjbWuMscPZw7jNF2WHsmCimrJBKKbU +cg9rHeUoLOw0357Mrg7gDwTBHefbqWlGA/bqOwY3N7F5jdS/2IAZ0WBndeKC/7bd +LqLNLSYG6H7VBHS9wmQ+YdzgIIPNOz+ghRJX/hV15vZbyW0ZzRIg3xTNty6mxpFk +kOu5Js1bu9TIpTWjdSyIYGBeBLp5z6Zs8c2oZu7cqGihAgMBAAGjXTBbMB8GA1Ud +IwQYMBaAFNCP2qqwSi+qkGYVmVZVIlEFjF5FMAkGA1UdEwQCMAAwCwYDVR0PBAQD +AgWgMCAGA1UdEQQZMBeCFWV4YW1wbGUubWl0bXByb3h5Lm9yZzANBgkqhkiG9w0B +AQsFAAOCAQEAOGGDdHBuqPhQXubWB3BNqILUSQn02ghs2mBG2unuXYukcQOTvW3e +eVTRNgPd/Ph9IcPJBcncKKjk+uW2dkbbM3BMQ1IZJoUuUjheWeV7fKrJML7l6gzi +3EHJ2Tx4wDOfx1M0FQK+aNZzbNKdzgFuhiPHHc32h7/srNltuYzzpB2iNj8MIi9Y +rJrAaHLQS/5GXyMfBX6Cz6sbneZRogMEygZwtl90+6HT6FoO8so8UcshTS0Jx4Qp +GtX3ktpjlJHvH8HZ3i15l+MhrEA17bEGO02yeg5T0ScZnMJ+0MoLoUPpwplYXN1U +/U5iwEc4J4dQtiyEbgbWIfKwzbyiLtI2RQ== +-----END CERTIFICATE----- diff --git a/test/mitmproxy/data/verificationcerts/trusted-leaf.key b/test/mitmproxy/data/verificationcerts/trusted-leaf.key new file mode 100644 index 000000000..78d972220 --- /dev/null +++ b/test/mitmproxy/data/verificationcerts/trusted-leaf.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAmUMaCGTHnvqsuxVThRtdUb+29+/31+TN0hv2eWVaFzb3c99/ +VC2iU0mqE19pf80KzM7uNtE8nxFy5K/8GVGlfRn2ZYtYGJ+jLtE2DkmPYbGgPfGh +yuXgMw+Dxkfh4LpqjfkhV23BZcOpI21rjLHD2cO4zRdlh7JgopqyQSim1HIPax3l +KCzsNN+ezK4O4A8EwR3n26lpRgP26jsGNzexeY3Uv9iAGdFgZ3Xigv+23S6izS0m +Buh+1QR0vcJkPmHc4CCDzTs/oIUSV/4Vdeb2W8ltGc0SIN8UzbcupsaRZJDruSbN +W7vUyKU1o3UsiGBgXgS6ec+mbPHNqGbu3KhooQIDAQABAoIBAA2kpYqdvg9u7TVy +Po8Y0oPWdyk3GW8ElTXg+13vIcfzQq/z81fBADQ92IAE/FU+IXn96cLDeYwHd5zX +9a8jT4IFb6O2dc8rVtFyGkfHUJY3w7X/7pErSXwCI47hE0B4F8gvp0IrKQ4wDrxy +nyJVKMQX4jmPnaAoxuVys++M+NzsbyLQ02KLtiB7YdIEZBiLLronm3vKfzzRJ506 +IxDtwknSvFTZ5KzJEHj1JlAs4DYSrV4wzoh75/xEYjbYDOc5vSFxn+qIlDzr7RdH +YWKl66fRuI5n+YZCd/WtyC+lHPtaNxZZhmX6h+L0Lxz6e3ePIlh1K17pNvEgI5yp +NOFCfakCgYEAxuGlm6GaRnYI7UCaNR8A4Ma9j99dV4lPkZRNreNxRf1hqmy02BYk +8XXl+u+xI+mcoswUpqj1qvPOfCI7UQD4ZMEjlpjJO0BpQAioyN1rmOz2sshsZHtI +coUtJjNhbJHyW62yuZKUjoGmyGOfyzyXmHYU2B06O5E7R90+vDO2K28CgYEAxUdj +IL6EOZ1sUD8DhaM/fpOuSqwVhjoCv3Mpn85Xb6DP1WPN2LEwdYZVk0Quhi81hidD +pPXBqSHf8Z7Z2GI+XNz1UcXBq6up/pOXREHN2OyzSvFuX0P/f8liXuu/KNbd/q/k +NBqOIwUU+n6DTbkyRjZqwfljOW8EVapMYDAJ5O8CgYBOpuJVoB1hDEEPguL5ax9v +xWkmQtGpUrZS/nGR+UbMxR4gxgjnBCrsCxI+oRhO+Y5mm4r3Ng6h4vWgBfGrYVTa +k789SYMbmaeGGWaWuWpZ+iy+G6EyQ8cs8xod52f6BeXw98qctSlnCkMpMKz7NSVG +uDwaE8T51b+59fdfepvqpQKBgClFC9m3wVWENzp6VDRKuGe0YUvBwCb6T8TZRKXn +tqblj1TmshNYzfhoB9Ls+oabrajI4f/KYZ8ONRkI0C3SL5Whq7hVlHRjTwawvX5L +/dIZglB1PU+0m+iRqoCM9MqIWJyFE0pLG9z7nS3h9Xn2+ityCtdVYoqLTO7W129v +3UIFAoGBALxSL2q/Qn2N2mA1iuNzZ/SIMTqgYWyxwCnIQnyJZm/VtpnWd/o2jKdT +affYTSuaIQwR4O4zg5DBFhVq9YYxmqiTwi9PqYGWCshssMNH4KARFPunoXOltNoa +E5SiVQrzxkvw7Jh/6uhFf1xTdZoHTnioOGTKV2X6Qu61OG29Zb81 +-----END RSA PRIVATE KEY----- diff --git a/test/mitmproxy/data/verificationcerts/trusted-root.crt b/test/mitmproxy/data/verificationcerts/trusted-root.crt new file mode 100644 index 000000000..0182d8cfd --- /dev/null +++ b/test/mitmproxy/data/verificationcerts/trusted-root.crt @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDazCCAlOgAwIBAgIUT0IDh7/Cho/ZPuVDs/jg7g/6+lswDQYJKoZIhvcNAQEL +BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0xOTExMjIyMjQxNDdaFw0zOTEx +MTcyMjQxNDdaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw +HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQCvx49WJyThnCZ/qQuotMpe1ZvokAfDmpS399815yn7 +kf2zsbuvb/nFGY6Y+tiaLOQkRqB7pV5fuolBng9Z5NDhu8Qw2WXAFDXQxpSsJVLx +lKyzt98RU8qoOuL9SipX2DjRMkBsm0FInCWeACWDWkn0DIPfW71FddtOIN2Q/kBE +LdpP9mZ4/RfJw6CpZXNvbwnTqwqOvpzpkaQDmbKFJwGFsKYyOctwEcE8qtR0YKs3 +5dCS/FTs6kc41V3ioaMBj2HaXwq+6R0I/939wrtwDKxFpH5NwES8T4oeSvnuszlk +o7Ot0IK4uCz8R+FCLZuRU9U+yP0KOdMRTZ9OBVMoLzxZAgMBAAGjUzBRMB0GA1Ud +DgQWBBTQj9qqsEovqpBmFZlWVSJRBYxeRTAfBgNVHSMEGDAWgBTQj9qqsEovqpBm +FZlWVSJRBYxeRTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQA9 +0R1JZJ/075J8ZJFvuYZURjD9D3NZdcp80X503UBXmNgkePVKOTlVlxStuuF87EY4 +BkUoqR+QE9xxr9uAyTX1xGMDEDCso0ylPmsT+p/uXdWzijNNQywg+X7/UprF20o+ +TPJNah+fQgcunvb3bjviOsIgSBFE8N9sNZLNTn1vc5mvKfzrT0svj5y31HwbOHmZ +85nyupjrrXzgDZBCIQLQpepfkjjOxm82oD3eszzNWe1x+ukvqKFWVQtUbP3hlclT +bgZuy/1NG4oZXgqGysNn0zxx4xixxbJhKb140TtH5xwAC08X3m5sTkcmDVjqJKWG +jemUYIi4o/YRxDEMChXT +-----END CERTIFICATE----- diff --git a/test/mitmproxy/data/verificationcerts/trusted-root.key b/test/mitmproxy/data/verificationcerts/trusted-root.key new file mode 100644 index 000000000..f2bfce84c --- /dev/null +++ b/test/mitmproxy/data/verificationcerts/trusted-root.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAr8ePVick4Zwmf6kLqLTKXtWb6JAHw5qUt/ffNecp+5H9s7G7 +r2/5xRmOmPrYmizkJEage6VeX7qJQZ4PWeTQ4bvEMNllwBQ10MaUrCVS8ZSss7ff +EVPKqDri/UoqV9g40TJAbJtBSJwlngAlg1pJ9AyD31u9RXXbTiDdkP5ARC3aT/Zm +eP0XycOgqWVzb28J06sKjr6c6ZGkA5myhScBhbCmMjnLcBHBPKrUdGCrN+XQkvxU +7OpHONVd4qGjAY9h2l8KvukdCP/d/cK7cAysRaR+TcBEvE+KHkr57rM5ZKOzrdCC +uLgs/EfhQi2bkVPVPsj9CjnTEU2fTgVTKC88WQIDAQABAoIBAQCPTS15mufiVZ69 +LF8o5lqk/Zfg/KqXuInNgPIjy5TaVqZxvE+6Mpt5J+CsrrOu3TIQsNNcefB6MmR7 +bhQtwPDZVm4XNORStyc4UOwbe0InWIGC8j+UrK7mfztWKwRiIRAQ29rRr7CFNWcl +bBEpCI6Juzo2+V9QJUjoZLq83coeybjswv+Iq4+j5u3KW8Ws1EAAj88SBHA2UAF1 +oIxoEv4jpyAPnTx0DEe3kJKwsLro7pQ9f2u2GY9ICfimcE7qEDnt+TIhDdi0nVuR +iY+Xvxi1HO4QHR3SJR+N6HAFOa9t0dhFLlrVv/0f9yZZjKPO+RGI5znX/ITqT3CE +VCBzy69RAoGBANbZpJt4T8NMiFj3V6ocXoAJxCzAzU3pO8IpDDn8t6tfgU+LNfEU +hv8pSJ70lsr/Qv/WjeVdEN9cQuBuOEeMPXQVfkqKA8J3pcpr8zY2nwxxw1A3H19Z +oaYP7YBx7RO5QVzAz+C5msSZSwGP5+5gTsZNRi0lpQBUst9tpooKGjs7AoGBANFy +PM4ITzk83CHMV5NGBcNSMSfQkhm50qJ7sMizhd13rC/iuuNDfDZWWSH2hkxspTSc +D8nTjnqxsSIWqojGQxgnVne/maitMK1TCWCIzQLgXjQjzKlwFNK8Fesw8foDAUD8 +Q+LajUQMVkqLGgxaOPAxFLWjp6POCziapC6QO+V7AoGATTAKBFT4Cwke3x+Vnibt +CID5ur5VxAzsDDhlDRwu/GGmemZgLcmbKmaxkXH8DtggQPvbJLEH08c4u5q9m27V +0TO7mJn2+dG0fYHE8hAzmevxKIt1OPNhsOB+Cixj6TcgNWuMA4eLA+Cy4s/Jmol9 +I581fBjPK8xCKyUgtO0mOWsCgYAXpWUWAbwoAyX7Lt3IQ8SMy6+/Bf4op2EPdRV9 +Yz8+xK8M7PUaiVjxrYf8nJ+G61EvglsJ9zeDxKHx7kssi+2xQWeyt0/6yirPtqs9 +WdSDeZ9JFa2ah4viStfSqMD47/PpSVHEv9XpE9d+LPww3tLE01W6OBLKHI4JwvO8 +Sg5pFwKBgEA0VO9UFijjm6fIARM6Fhdpq0PZDiuPodWrAD3z0C5V6mR4ecgkUIcN +sBvQErzxA9dcUv5D3dPtqP7RIk5+lGfNn0Dqm8Ynr0V018Cojxi6hmmCoXvJNR68 +y81DA04Kbo4mjScGxxawN7IfvXRQ5RNPXAuAcw7bEn1RzRlfHiFU +-----END RSA PRIVATE KEY----- diff --git a/test/mitmproxy/data/verificationcerts/trusted-root.srl b/test/mitmproxy/data/verificationcerts/trusted-root.srl new file mode 100644 index 000000000..62570f55c --- /dev/null +++ b/test/mitmproxy/data/verificationcerts/trusted-root.srl @@ -0,0 +1 @@ +3E87AEF68CE27F7396C3309503BB595AD9732F3F diff --git a/test/mitmproxy/proxy2/layers/test_tls.py b/test/mitmproxy/proxy2/layers/test_tls.py index 68637d54a..ab044aa8b 100644 --- a/test/mitmproxy/proxy2/layers/test_tls.py +++ b/test/mitmproxy/proxy2/layers/test_tls.py @@ -69,16 +69,20 @@ class SSLTest: """Helper container for Python's builtin SSL object.""" def __init__(self, server_side: bool = False, alpn: typing.Optional[typing.List[str]] = None, - sni: typing.Optional[bytes] = b"example.com"): + sni: typing.Optional[bytes] = b"example.mitmproxy.org"): self.inc = ssl.MemoryBIO() self.out = ssl.MemoryBIO() - self.ctx = ssl.SSLContext() + self.ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER if server_side else ssl.PROTOCOL_TLS_CLIENT) if alpn: self.ctx.set_alpn_protocols(alpn) if server_side: self.ctx.load_cert_chain( - certfile=tlsdata.path("../../net/data/verificationcerts/trusted-root.crt"), - keyfile=tlsdata.path("../../net/data/verificationcerts/trusted-root.key"), + certfile=tlsdata.path("../../data/verificationcerts/trusted-leaf.crt"), + keyfile=tlsdata.path("../../data/verificationcerts/trusted-leaf.key"), + ) + else: + self.ctx.load_verify_locations( + cafile=tlsdata.path("../../data/verificationcerts/trusted-root.crt"), ) self.obj = self.ctx.wrap_bio( self.inc, @@ -106,7 +110,9 @@ class TlsEchoLayer(tutils.EchoLayer): def _handle_event(self, event: events.Event) -> commands.TCommandGenerator: if isinstance(event, events.DataReceived) and event.data == b"establish-server-tls": # noinspection PyTypeChecker - self.err = yield tls.EstablishServerTLS(self.context.server) + err = yield tls.EstablishServerTLS(self.context.server) + if err: + yield commands.SendData(event.connection, f"server-tls-failed: {err}".encode()) else: yield from super()._handle_event(event) @@ -121,7 +127,7 @@ def interact(playbook: tutils.Playbook, conn: context.Connection, tssl: SSLTest) tssl.inc.write(data()) -def reply_tls_start(alpn: typing.Optional[bytes] = None,*args, **kwargs) -> tutils.reply: +def reply_tls_start(alpn: typing.Optional[bytes] = None, *args, **kwargs) -> tutils.reply: """ Helper function to simplify the syntax for tls_start hooks. """ @@ -132,10 +138,14 @@ def reply_tls_start(alpn: typing.Optional[bytes] = None,*args, **kwargs) -> tuti ssl_context = SSL.Context(SSL.SSLv23_METHOD) if tls_start.conn == tls_start.context.client: ssl_context.use_privatekey_file( - tlsdata.path("../../net/data/verificationcerts/trusted-leaf.key") + tlsdata.path("../../data/verificationcerts/trusted-leaf.key") ) ssl_context.use_certificate_chain_file( - tlsdata.path("../../net/data/verificationcerts/trusted-leaf.crt") + tlsdata.path("../../data/verificationcerts/trusted-leaf.crt") + ) + else: + ssl_context.load_verify_locations( + cafile=tlsdata.path("../../data/verificationcerts/trusted-root.crt") ) if alpn is not None: if tls_start.conn == tls_start.context.client: @@ -145,6 +155,26 @@ def reply_tls_start(alpn: typing.Optional[bytes] = None,*args, **kwargs) -> tuti tls_start.ssl_conn = SSL.Connection(ssl_context) + if tls_start.conn != tls_start.context.client: + # Set SNI + tls_start.ssl_conn.set_tlsext_host_name(tls_start.conn.sni) + + # Manually enable hostname verification. + # Recent OpenSSL versions provide slightly nicer ways to do this, but they are not exposed in + # cryptography and likely a PITA to add. + # https://wiki.openssl.org/index.php/Hostname_validation + param = SSL._lib.SSL_get0_param(tls_start.ssl_conn._ssl) + # Common Name matching is disabled in both Chrome and Firefox, so we should disable it, too. + # https://www.chromestatus.com/feature/4981025180483584 + SSL._lib.X509_VERIFY_PARAM_set_hostflags( + param, + SSL._lib.X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS | SSL._lib.X509_CHECK_FLAG_NEVER_CHECK_SUBJECT + ) + SSL._openssl_assert( + SSL._lib.X509_VERIFY_PARAM_set1_host(param, tls_start.conn.sni, 0) == 1 + ) + SSL._lib.SSL_set_verify(tls_start.ssl_conn._ssl, SSL.VERIFY_PEER, SSL._ffi.NULL) + return tutils.reply(*args, side_effect=make_conn, **kwargs) @@ -167,7 +197,8 @@ class TestServerTLS: layer = tls.ServerTLSLayer(tctx) playbook = tutils.Playbook(layer) tctx.server.connected = True - tctx.server.address = ("example.com", 443) + tctx.server.address = ("example.mitmproxy.org", 443) + tctx.server.sni = b"example.mitmproxy.org" tssl = SSLTest(server_side=True) @@ -202,6 +233,41 @@ class TestServerTLS: # Echo _test_echo(playbook, tssl, tctx.server) + def test_untrusted_cert(self, tctx): + """If the certificate is not trusted, we should fail.""" + layer = tls.ServerTLSLayer(tctx) + playbook = tutils.Playbook(layer) + tctx.server.connected = True + tctx.server.address = ("wrong.host.mitmproxy.org", 443) + tctx.server.sni = b"wrong.host.mitmproxy.org" + + tssl = SSLTest(server_side=True) + + # send ClientHello + data = tutils.Placeholder() + assert ( + playbook + >> events.DataReceived(tctx.client, b"establish-server-tls") + << commands.Hook("next_layer", tutils.Placeholder()) + >> tutils.reply_next_layer(TlsEchoLayer) + << commands.Hook("tls_start", tutils.Placeholder()) + >> reply_tls_start() + << commands.SendData(tctx.server, data) + ) + + # receive ServerHello, finish client handshake + tssl.inc.write(data()) + with pytest.raises(ssl.SSLWantReadError): + tssl.obj.do_handshake() + + assert ( + playbook + >> events.DataReceived(tctx.server, tssl.out.read()) + << commands.SendData(tctx.client, + b"server-tls-failed: Error([('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')])") + ) + assert not tctx.server.tls_established + def _make_client_tls_layer(tctx: context.Context) -> typing.Tuple[tutils.Playbook, tls.ClientTLSLayer]: # This is a bit contrived as the client layer expects a server layer as parent. @@ -214,15 +280,13 @@ def _make_client_tls_layer(tctx: context.Context) -> typing.Tuple[tutils.Playboo return playbook, client_layer -def _test_tls_client_server( - tctx: context.Context, - sni: typing.Optional[bytes] = b"example.com", - alpn: typing.Optional[typing.List[str]] = None -) -> typing.Tuple[tutils.Playbook, tls.ClientTLSLayer, SSLTest]: +def _test_tls_client_server(tctx: context.Context, **kwargs) -> typing.Tuple[ + tutils.Playbook, tls.ClientTLSLayer, SSLTest]: playbook, client_layer = _make_client_tls_layer(tctx) tctx.server.tls = True - tctx.server.address = ("example.com", 443) - tssl_client = SSLTest(sni=sni, alpn=alpn) + tctx.server.address = ("example.mitmproxy.org", 443) + tctx.server.sni = b"example.mitmproxy.org" + tssl_client = SSLTest(**kwargs) # Send ClientHello with pytest.raises(ssl.SSLWantReadError): @@ -296,7 +360,7 @@ class TestClientTLS: to establish TLS with the client. """ tssl_server = SSLTest(server_side=True, alpn=["quux"]) - playbook, client_layer, tssl_client = _test_tls_client_server(tctx, sni=None, alpn=["quux"]) + playbook, client_layer, tssl_client = _test_tls_client_server(tctx, alpn=["quux"]) # We should now get instructed to open a server connection. data = tutils.Placeholder()