Conversation
Related to php#16766
Sjord
commented
Oct 1, 2026
This was referenced Oct 2, 2026
|
@Sjord: Thanks a lot for your work about Channel Binding! It will be not possible to backport to previous PHP versions too? |
This was referenced Oct 2, 2026
Member
and
If it's part of OpenSSL, it must have an |
This was referenced Oct 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Related to #16766
The branch adds a new function to the openssl extension:
It extracts TLS channel binding data from an established
tls://socket stream. This unblocks SASL channel binding (SCRAM-SHA-*-PLUSper RFC 5802 and RFC 5801) for clients written in PHP, which previously had no way to obtain the binding material that those mechanisms require.The accepted binding types are the names from the IANA "Channel Binding" registry, matching the spelling and semantics used by CPython's
_ssl.get_channel_binding().streamresourcessl:///tls://). Must be in the connected/active state.channel_binding_typestring"tls-unique","tls-server-end-point","tls-exporter"(case-sensitive).Return value
nullwhen the requested type is not applicable to the connection(currently:
"tls-unique"over TLS 1.3, where the type is not defined).Errors / exceptions
channel_binding_typeis not one of the three known typesValueError(checked before the stream is inspected)streamis not a stream resourceTypeErrorstreamis a stream but has no active TLS transportRuntimeException—"Stream does not have transport encryption enabled"RuntimeException—"Failed to get channel binding data: <OpenSSL error>"Supported channel binding types
tls-uniquenulltls-server-end-pointtls-exporterEXPORTER-Channel-Bindingand an empty contextNotes on semantics
tls-uniqueselection. In a full handshake both endpoints transmit aFinished message; in a resumed handshake only the server does. The
implementation picks between the local
SSL_get_finished()andSSL_get_peer_finished()usingis_client ^ SSL_session_reused(), so that theclient and the server always derive the same value. This mirrors the
selection made by CPython's
_ssl.get_channel_binding().tls-server-end-pointdigest choice. The digest algorithm is taken fromthe certificate's own signature algorithm. If that algorithm is MD5 or SHA-1,
or cannot be determined, SHA-256 is used instead (as mandated by
RFC 5929 §4.1). For a SHA-256-signed certificate the result equals
openssl_x509_fingerprint($cert, "sha256", true). On the client side the peercertificate is used; on the server side the local certificate is used.
tls-exporter. Computed withSSL_export_keying_material()using a 32octet output, the label
EXPORTER-Channel-Bindingand an empty context(RFC 9266 §4 / RFC 5705).
Example
Obtaining each binding on a connected client and using one as the SASL
cbproperty for aSCRAM-SHA-256-PLUSnegotiation: