Skip to content

Commit

Permalink
tidied up #1815
Browse files Browse the repository at this point in the history
  • Loading branch information
MadsRC committed Apr 5, 2024
1 parent a2219eb commit 71f4f5d
Show file tree
Hide file tree
Showing 5 changed files with 153 additions and 2 deletions.
33 changes: 33 additions & 0 deletions tests/server.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
-----BEGIN CERTIFICATE-----
MIIFozCCA4ugAwIBAgIUYFGwS/vDAQNfUry6qiNhr7c6xvYwDQYJKoZIhvcNAQEL
BQAwYTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEaMBgGA1UEAwwRdXZpY29ybi5sb2Nh
bGhvc3QwHhcNMjQwNDA1MDc1MjU0WhcNMzQwNDAzMDc1MjU0WjBhMQswCQYDVQQG
EwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lk
Z2l0cyBQdHkgTHRkMRowGAYDVQQDDBF1dmljb3JuLmxvY2FsaG9zdDCCAiIwDQYJ
KoZIhvcNAQEBBQADggIPADCCAgoCggIBAMxgwPo6zf6NeB3UFieLSTsZ0h2HB8Nx
YlV4Mh4fhlk6YXr5xNuFCgV5Q4ZVGA5tjlphaTxSfQLpH+Wo6LX1Xj6xoPGrGtCp
rfW6VaL/AByVSXKFPsyW32BjsXgLmIg63eh9lLBjKpH/M8/YfR4xqFDnassYyRxw
OJ+OFLmKkvG8QNN4Z14sqYL5gg7bnAeCEj+kZowuaW5yCCbArwii+eGTS0P5Mufh
xD/TlclWnNA1EO1NVSbimj3FkZ3vqqRK6bUu0HEPoaoLOkdsY4JFbFMGl3x+dc9u
LJuBNFnnGHQgHwxrughAf2+tvSnOdofWUFI/1LaNdUo+qN6rATdbbyAYLfn7aR/f
PwrTmNBG8GYd3FVQEw6hfRNGr4pHo6awC7izb7DAssxDkwetxuhXXO2fB5N04UYF
ZlQAxrDCORlo9atUexZMTOvQIUHaHFeIj+HasTBs+D0gEQRgvQbA0+orpyF1yczV
7laMvY/41BOvLoPaY8GQ33WrDFxuO2tRV7RF4+5rozC951nP78dU0cG5VXS2UqIj
hz2A3iYEjSc52uKMdEdlfdPkDYI8v4qivnv7J893i3rcAWeRqzkXnHRwPfobCtG/
Nnbgo9fwuqbIVLBNAw02JCgSYbLLRxgcMwV9t8Jj5Xd06v35lL1gunsKg6aPRH7g
5hYecI271akrAgMBAAGjUzBRMB0GA1UdDgQWBBQzMQrX2PX397oBZwfl98mw1fmd
MTAfBgNVHSMEGDAWgBQzMQrX2PX397oBZwfl98mw1fmdMTAPBgNVHRMBAf8EBTAD
AQH/MA0GCSqGSIb3DQEBCwUAA4ICAQAf36TLtdQOChLeQok5Vr9x2woyxYROr3XA
V0GO/ZLxTJsRGXwb5GP/3vr1g0gmsEFWi4lYhlxmOPY12zQShf772IncgS8o2TYg
NMoEqBRlTlWVXbyHZGXcKEdQ6Vlt/yvscJ8c30AYPIJRDzsI8W8BehKMxevnSSKh
+tdViEVU1T0bck1pgLyc2gkV64ZlnjPFFT5s65TGTp+DGzsDkExMPwQ3GE0mzWEU
dKLjAHK0VHqmanXmrhWIG2/oKVQybHqP7Df+8HFz54G4ubxdixR8LU6dV630xoAt
/s6+BvdpplQoWS+WZhgFoOcpr36DoUNboZn0c0QGGKP/aqf6RwQFCyDurmkasXRi
6JGMcMt0NFDMykTkuY6UkDcOIINhUqfrNkF7qwuOwfgWB7xB2d4i/9YLofxZo3wK
Hc317ATQRgKzI/1igPaW7bk6pJxhpYCsvgWyi0MSFctvN+R3J+AKJiQAg9RmvFRJ
Xet4mnj+aEDDp7k8KemHxHN9bCIkeHU2ZvvVPS5PzSkPbK/JyfcMpraXfOAHdKVv
kRLll+7G4itsu45MzQnh6qq5bR7b18Qgee3o8iKfZKCzct7HEUU91H89jfCCl62L
V6L2pS4YXe8N3Bdjc5aSy3lAw6RiDzR3eoQaLzqLd3RyAEp7/UmptwWhaHOUNma+
IeY7UK1ylg==
-----END CERTIFICATE-----
52 changes: 52 additions & 0 deletions tests/server.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
-----BEGIN PRIVATE KEY-----
MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQDMYMD6Os3+jXgd
1BYni0k7GdIdhwfDcWJVeDIeH4ZZOmF6+cTbhQoFeUOGVRgObY5aYWk8Un0C6R/l
qOi19V4+saDxqxrQqa31ulWi/wAclUlyhT7Mlt9gY7F4C5iIOt3ofZSwYyqR/zPP
2H0eMahQ52rLGMkccDifjhS5ipLxvEDTeGdeLKmC+YIO25wHghI/pGaMLmlucggm
wK8Iovnhk0tD+TLn4cQ/05XJVpzQNRDtTVUm4po9xZGd76qkSum1LtBxD6GqCzpH
bGOCRWxTBpd8fnXPbiybgTRZ5xh0IB8Ma7oIQH9vrb0pznaH1lBSP9S2jXVKPqje
qwE3W28gGC35+2kf3z8K05jQRvBmHdxVUBMOoX0TRq+KR6OmsAu4s2+wwLLMQ5MH
rcboV1ztnweTdOFGBWZUAMawwjkZaPWrVHsWTEzr0CFB2hxXiI/h2rEwbPg9IBEE
YL0GwNPqK6chdcnM1e5WjL2P+NQTry6D2mPBkN91qwxcbjtrUVe0RePua6MwvedZ
z+/HVNHBuVV0tlKiI4c9gN4mBI0nOdrijHRHZX3T5A2CPL+Kor57+yfPd4t63AFn
kas5F5x0cD36GwrRvzZ24KPX8LqmyFSwTQMNNiQoEmGyy0cYHDMFfbfCY+V3dOr9
+ZS9YLp7CoOmj0R+4OYWHnCNu9WpKwIDAQABAoICADj4dYKrNrXRAJ0r/Br80CaJ
3ZC+jbL03cjebvYHqp8fz4GEs1PP44nAEksVWFXZQze9dKTMh61yh6IwseHa6nEG
ecsz+48T5XqcfPepJoJROP6T1vwXyF+pmpRQgy3iXu5KZ1K96eV1op87BTGP/Q/E
WngPyivDunz7kZpg3vJEnDt2kjXltEDexVrX68gKAYU9EhrcayZO4ifPSVtadtZj
BTWG9yI9REPYeqX7n03IpRXJG0XyH7W9Z4iDgOk4Oqp3SMJjbZildZLoS1rKeFYy
fbLF25g9aXDVlN7EtQPV2mHPe7WGKR/b6eGH/HGEE7LBuU1D5GCUU+Vx/K5OLgzf
ybg0uO04WbHKWrdml4DMJjaxUL0NsZ+CYgtXK0KRiCMNsxzzRCdSO2WelHFSY87X
rlDh6sFgpWwAGMsiG/6BVfw6xdIfiD61tf3hZCiqZ5KBav7RTv5z+1E2lzc5xlJS
LVWpQmYxcKj7CW5+PRMPfLbM7ClrhKWxjo9oGeqy59qFvYqf5LFTNYBm/ZjGDTN6
bGXxonFr7L+rR2/KoRzPAh+DerZRShN7UsUPtMAhfBJVYUrT2QE9UwipK/scuFCR
YGeNZ80yq3N7mIvtEp0XmSzINGCzZ0S81uLA235GgHEcBaq9dD5hpDsz16gpvO3/
YzwvN9+i03L/MXZK45lxAoIBAQD4kWIHisQeoD29XK/RbMpMWRhREfYxDO4onrh9
qlCGS6w5oHfS3pR7hRgDo2LGRMlLQKheWc60XfggHOnhszO8wYCz6TQ0gI6hYA+J
RPyWIxVgqq4J0bTJDcz6LIEJGiIdrL5pASyz6/z2flVDhfqOLELv3huCTv2I2yLr
Dd7EmKS2A9swEDKyq29yc9ELTcpQMcFc8Ja+5vXvsX5nSOfnztKmJwIPm9VKZZ3P
aLAZUVQRlQPY7YHzh7LZUtdqG317LtNW3RFuxZ+cdaCu7gvlDTL762ecjtaQ14mB
HqYLcHnaUUy9ItNSqh5rV+WIy40moB4xUpYeXevR3pZgVMabAoIBAQDSfSCE3Hl0
3b8UeeLopdgtl9qYVmxzAcuWSoeZolF+G1KNE0Sx3XVX0A5W/Ziu4KV64O0IVsCJ
bnpc72CN1+ouJ74uudmqhK0WIz7dweEWXZFR8pt3dxydI0aeyVWagCMJB3wIvXNe
tZnOfXuGG5HEhJRJIfYFSWJnO1JZOZM8j+aAhd/FKk+NkPBgf0Bfck1qOF802/OU
WkZ82Mjoo0y48J+8kUBuS5ZO9kUKmRNF33pjQVVzjpBGJIxIOw/drNYAp84dUZTd
4X9wICASDkS+6UmaTx6SZuXQKLK/qYMgaN3Rs/SzSAVhROd8bcqITVNpTFKD0mGv
Fl+jaRcHgoixAoIBAF+frlKwc5pEkvvSOGEctQaCD/TAMDHWg5hk1xyg9LF1UyAo
N3CL6BtMrFxZ8pnLxJSKnzsM2ZRRwi64cNE/G1w2JMkRod/AxR4X0mJAg9tOS98Q
SjvEzQO7p2tmy40w3IcF+YpzxTrCQmKhXzPGywj+xhF5JKQQt0B67Qf4IgcHofXT
rfLjiF1rzkf9fiIXHwmS2oxikduHBn3bjoE1buGiky8QOp6+mGMyjG9KGtTikLDi
3sQJOsDxJ0Crues8AB3veaYlDZvLsweByPsC4NiRJ1f6y7VSzgCSqnddzwr/jiEK
vbbVOu7GO0WYXtktVXPSjUr0NoQgJaRrOPZ+JpkCggEAQNrfBzDrl2+vrX50xNw8
xKeSaffPCIyYDyG9sD/MPj/q6p7yPp+OxVTM5k7TGacMNdVSE4yvXGkW+MWlCW9q
r3f9aGZJQ/oHXtfTSf6v/PUtjoNjFac0wNIas1gzsRwkL2cH96VwA9GOp4oQYlzi
SBvVmMcHB8/5qvcjQ2yzCikIi7c0IIsN4f+zoPf0fLQ6WC0wYJgY8C/0ogkltlCC
lkVF4pMauCFAGepVkZNi1deq3SRHUQivOX2PX74bAGF9usv5fR0i8k7FtmWfnBCb
a/tze0E/mTptOvsfQGDZj0XgevmovwjE55iUfslRazfwKHSkxAsxoAITy8TYnK7C
sQKCAQEA6X5Dwx+n8rq73MQX9QmqQ9jux9JAh7DHcH2ZGh6BksD78FAQLZ7vjT9N
PE/9vY4KXRg1NdoH1yFncV2I+8P/sTBL2v3nmo2Z9Ui3dP/nnHqeBV757VsIkJCq
JHtGretK1TElHwTxdu86yLOHNBXvto+MYIJkqr9ENVjjiG8hdtaMRkwMnp9jrk9M
9k0iNQwA9FYGokba3+Gz8o+3XzoPhzkPKGfMrsh7gEgFeRpnoBk9Ox614BAVWrz/
4GtuXAwz0JgebhD29pUUpdQ46SgQys/o6MLh53UpnoREJ8dGQkIcmMNgKshck3Ia
n+nYHLy1vGIssY5ODapJLixk/nt/Jg==
-----END PRIVATE KEY-----
30 changes: 30 additions & 0 deletions tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import logging
import os
import socket
import ssl
import sys
import typing
from pathlib import Path
Expand Down Expand Up @@ -279,6 +280,35 @@ def test_ssl_config(
assert config.is_ssl is True


def ssl_context():
context = ssl.SSLContext(int(ssl.PROTOCOL_TLS_SERVER))
allowed_ciphers = "DEFAULT:!aNULL:!eNULL:!MD5:!3DES:!DES:!RC4:!IDEA:!SEED:!aDSS:!SRP:!PSK"
context.set_ciphers(allowed_ciphers)
list_options = [ssl.OP_NO_RENEGOTIATION]
for each_option in list_options:
context.options |= each_option
return context


def test_ssl_context() -> None:
config = Config(app=asgi_app, ssl_context=ssl_context)
config.load()
if config.ssl_context is not None:
assert ssl.PROTOCOL_TLS_SERVER is config.ssl_version
assert "TLSv1" in config.ssl_ciphers
if config.ssl is not None:
assert ssl.OP_NO_RENEGOTIATION in config.ssl.options


def test_ssl_context_load_cert() -> None:
config = Config(
app=asgi_app, ssl_context=ssl_context, ssl_certfile="tests/server.crt", ssl_keyfile="tests/server.key"
)
config.load()
assert config.ssl_context is not None
ctx = ssl_context()


def test_ssl_config_combined(tls_certificate_key_and_chain_path: str) -> None:
config = Config(
app=asgi_app,
Expand Down
38 changes: 36 additions & 2 deletions uvicorn/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,27 @@
logger = logging.getLogger("uvicorn.error")


def update_ssl_context(
ctx: ssl.SSLContext,
certfile: str | os.PathLike[str] | None,
keyfile: str | os.PathLike[str] | None,
password: str | None,
cert_reqs: int,
ca_certs: str | os.PathLike[str] | None,
ciphers: str | None,
) -> ssl.SSLContext:
get_password = (lambda: password) if password else None
if certfile and keyfile:
ctx.load_cert_chain(certfile, keyfile, get_password)
if cert_reqs:
ctx.verify_mode = ssl.VerifyMode(cert_reqs)
if ca_certs:
ctx.load_verify_locations(ca_certs)
if ciphers:
ctx.set_ciphers(ciphers)
return ctx


def create_ssl_context(
certfile: str | os.PathLike[str],
keyfile: str | os.PathLike[str] | None,
Expand Down Expand Up @@ -219,6 +240,7 @@ def __init__(
ssl_cert_reqs: int = ssl.CERT_NONE,
ssl_ca_certs: str | None = None,
ssl_ciphers: str = "TLSv1",
ssl_context: Callable[[], Any] | None = None,
headers: list[tuple[str, str]] | None = None,
factory: bool = False,
h11_max_incomplete_event_size: int | None = None,
Expand Down Expand Up @@ -263,6 +285,7 @@ def __init__(
self.ssl_cert_reqs = ssl_cert_reqs
self.ssl_ca_certs = ssl_ca_certs
self.ssl_ciphers = ssl_ciphers
self.ssl_context = ssl_context
self.headers: list[tuple[str, str]] = headers or []
self.encoded_headers: list[tuple[bytes, bytes]] = []
self.factory = factory
Expand Down Expand Up @@ -394,9 +417,19 @@ def configure_logging(self) -> None:
def load(self) -> None:
assert not self.loaded

if self.is_ssl:
if self.ssl_context:
self.ssl: ssl.SSLContext | None = update_ssl_context(
self.ssl_context(),
keyfile=self.ssl_keyfile,
certfile=self.ssl_certfile,
password=self.ssl_keyfile_password,
cert_reqs=self.ssl_cert_reqs,
ca_certs=self.ssl_ca_certs,
ciphers=self.ssl_ciphers,
)
elif self.is_ssl and not self.ssl_context:
assert self.ssl_certfile
self.ssl: ssl.SSLContext | None = create_ssl_context(
self.ssl = create_ssl_context(
keyfile=self.ssl_keyfile,
certfile=self.ssl_certfile,
password=self.ssl_keyfile_password,
Expand All @@ -405,6 +438,7 @@ def load(self) -> None:
ca_certs=self.ssl_ca_certs,
ciphers=self.ssl_ciphers,
)

else:
self.ssl = None

Expand Down
2 changes: 2 additions & 0 deletions uvicorn/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,7 @@ def run(
ssl_cert_reqs: int = ssl.CERT_NONE,
ssl_ca_certs: str | None = None,
ssl_ciphers: str = "TLSv1",
ssl_context: Callable[[], Any] | None = None,
headers: list[tuple[str, str]] | None = None,
use_colors: bool | None = None,
app_dir: str | None = None,
Expand Down Expand Up @@ -553,6 +554,7 @@ def run(
ssl_cert_reqs=ssl_cert_reqs,
ssl_ca_certs=ssl_ca_certs,
ssl_ciphers=ssl_ciphers,
ssl_context=ssl_context,
headers=headers,
use_colors=use_colors,
factory=factory,
Expand Down

0 comments on commit 71f4f5d

Please sign in to comment.