Skip to content

Commit e44c79e

Browse files
authored
Add require_cbt support on HTTP (not S) server (#4726)
1 parent d7ce0e4 commit e44c79e

File tree

2 files changed

+26
-13
lines changed

2 files changed

+26
-13
lines changed

scapy/layers/gssapi.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -346,9 +346,13 @@ def fromssl(
346346
# RFC5929 sect 4.1
347347
if h == hashes.MD5 or h == hashes.SHA1:
348348
h = hashes.SHA256
349+
# Get bytes of first certificate if there are multiple
350+
c = cert.x509Cert.copy()
351+
c.remove_payload()
352+
cdata = bytes(c)
349353
# Calc hash of certificate
350354
digest = hashes.Hash(h)
351-
digest.update(bytes(cert.x509Cert))
355+
digest.update(cdata)
352356
cbdata = digest.finalize()
353357
elif token_type == ChannelBindingType.TLS_UNIQUE:
354358
# RFC5929 sect 3
@@ -414,7 +418,7 @@ class CONTEXT:
414418

415419
__slots__ = ["state", "_flags", "passive"]
416420

417-
def __init__(self, req_flags: Optional['GSS_C_FLAGS | GSS_S_FLAGS'] = None):
421+
def __init__(self, req_flags: Optional["GSS_C_FLAGS | GSS_S_FLAGS"] = None):
418422
if req_flags is None:
419423
# Default
420424
req_flags = (

scapy/layers/http.py

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,6 +1027,9 @@ class HTTP_Server(Automaton):
10271027
10281028
:param ssp: the SSP to serve. If None, unauthenticated (or basic).
10291029
:param mech: the HTTP_AUTH_MECHS to use (default: NONE)
1030+
:param require_cbt: require Channel Bindings to be valid (default: False)
1031+
:param cbt_cert: the path to the certificate used for channel bindings.
1032+
Useful if behind a reverse proxy. (default: None)
10301033
10311034
Other parameters:
10321035
@@ -1042,6 +1045,8 @@ def __init__(
10421045
mech=HTTP_AUTH_MECHS.NONE,
10431046
verb=True,
10441047
ssp=None,
1048+
require_cbt: bool = False,
1049+
cbt_cert: str = None,
10451050
*args,
10461051
**kwargs,
10471052
):
@@ -1053,8 +1058,20 @@ def __init__(
10531058
self.ssp = ssp
10541059
self.authmethod = mech.value
10551060
self.sspcontext = None
1061+
1062+
# CBT settings
10561063
self.ssp_req_flags = GSS_S_FLAGS.GSS_S_ALLOW_MISSING_BINDINGS
1057-
self.chan_bindings = GSS_C_NO_CHANNEL_BINDINGS
1064+
if require_cbt:
1065+
self.ssp_req_flags &= ~GSS_S_FLAGS.GSS_S_ALLOW_MISSING_BINDINGS
1066+
if cbt_cert:
1067+
self.chan_bindings = GssChannelBindings.fromssl(
1068+
ChannelBindingType.TLS_SERVER_END_POINT,
1069+
certfile=cbt_cert,
1070+
)
1071+
else:
1072+
self.chan_bindings = GSS_C_NO_CHANNEL_BINDINGS
1073+
1074+
# Auth settings
10581075
self.basic = False
10591076
self.BASIC_IDENTITIES = kwargs.pop("BASIC_IDENTITIES", {})
10601077
self.BASIC_REALM = kwargs.pop("BASIC_REALM", "default")
@@ -1311,16 +1328,8 @@ def __init__(
13111328
mech=mech,
13121329
verb=verb,
13131330
ssp=ssp,
1331+
cbt_cert=cert,
1332+
require_cbt=require_cbt,
13141333
*args,
13151334
**kwargs,
13161335
)
1317-
1318-
# Set channel binding
1319-
if cert:
1320-
self.chan_bindings = GssChannelBindings.fromssl(
1321-
ChannelBindingType.TLS_SERVER_END_POINT,
1322-
certfile=cert,
1323-
)
1324-
if require_cbt:
1325-
# We require CBT by removing GSS_S_ALLOW_MISSING_BINDINGS
1326-
self.ssp_req_flags &= ~GSS_S_FLAGS.GSS_S_ALLOW_MISSING_BINDINGS

0 commit comments

Comments
 (0)