On Wednesday, January 11, 2017, Christian Heimes <christ...@cheimes.de> wrote:
On 2017-01-11 20:01, Cory Benfield wrote: > > > The ``Context`` abstract base class defines an object that allows > configuration > > of TLS. It can be thought of as a factory for ``TLSWrappedSocket`` and > > ``TLSWrappedBuffer`` objects. > > > > The ``Context`` abstract base class has the following class definition:: > > > > TLSBufferObject = Union[TLSWrappedSocket, TLSWrappedBuffer] > > ServerNameCallback = Callable[[TLSBufferObject, Optional[str], > Context], Any] > > > > class _BaseContext(metaclass=ABCMeta): > > > > @property > > @abstractmethod > > def validate_certificates(self) -> bool: > > """ > > Whether to validate the TLS certificates. This switch > operates at a > > very broad scope: either validation is enabled, in which > case all > > forms of validation are performed including hostname > validation if > > possible, or validation is disabled, in which case no > validation is > > performed. > > > > Not all backends support having their certificate validation > > disabled. If a backend does not support having their > certificate > > validation disabled, attempting to set this property to > ``False`` > > will throw a ``TLSError``. > > """ > > > > @validate_certificates.setter > > @abstractmethod > > def validate_certificates(self, val: bool) -> None: > > pass > > > For 3.7 I'm planning to replace ssl.match_hostname() with OpenSSL > 1.0.2's API. For now the one flag is enough. Later we can discuss > settings for wildcard, IP address and CN matching. > > > > > @abstractmethod > > def register_certificates(self, > > certificates: str, > > key=None: Optional[str], > > password=None: Optional[Callable[[], > Union[AnyStr, bytearray]]]) -> None: > > """ > > Loads a certificate, a number of intermediate certificates, > and the > > corresponding private key. These certificates will be > offered to > > the remote peer during the handshake if required. > > > > The ``certificates`` argument must be a bytestring > containing the > > PEM-encoded certificates. The first PEM-encoded certificate > must be > > the leaf certificate. All subsequence certificates will be > offered > > as intermediate additional certificates. > > > > The ``key`` argument, if present, must contain the > PEM-encoded > > private key associated with the leaf certificate. If not > present, > > the private key will be extracted from ``certificates``. > > > > The ``password`` argument may be a function to call to get > the > > password for decrypting the private key. It will only be > called if > > the private key is encrypted and a password is necessary. It > will > > be called with no arguments, and it should return a string, > bytes, > > or bytearray. If the return value is a string it will be > encoded as > > UTF-8 before using it to decrypt the key. Alternatively a > string, > > bytes, or bytearray value may be supplied directly as the > password > > argument. It will be ignored if the private key is not > encrypted > > and no password is needed. > > """ > > I don't think this function works for all libraries and use cases. For > some implementations the order of certificates is very important. For > NSS and PKCS#11 we rather need to specify the slot or nick name of the > cert. For 3.7 I also like to introduce X509 objects and EVP_Key wrapper, > so this function would need to consume a stack of certificates. > > Since this function is only required for TLS servers and TLS client cert > authentication, I'd rather mark this function provisional or not define > it in the first version. > > > This may be a bit of a different use case (and possibly worth having in the first version of a new tls module): "Hitless TLS Certificate Rotation in Go" https://diogomonica.com/2017/01/11/hitless-tls-certificate-rotation-in-go/ - Can/could this be done with only set_sni_callback ? - VerifyPeerCertificate https://github.com/golang/go/issues/16363 - https://github.com/golang/go/blob/release-branch.go1.8/ src/crypto/tls/common.go#L406 > > > @abstractmethod > > def set_ciphers(self, ciphers: List[Ciphers]) -> None: > > """ > > Set the available ciphers for TLS connections created with > this > > context. ``ciphers`` should be a list of ciphers from the > > ``Cipher`` registry. If none of the ``ciphers`` provided to > this > > object are supported or available, a ``TLSError`` will be > raised. > > """ > > Implementors should initial context with sensible default settings, > preferable system-wide settings. For example Fedora is currently > implementing https://fedoraproject.org/wiki/Changes/CryptoPolicy for > OpenSSL, NSS and GnuTLS. > > > > > > > @abstractmethod > > def set_inner_protocols(self, protocols: List[NextProtocol]) -> > None: > > """ > > Specify which protocols the socket should advertise as > supported > > during the TLS handshake. This may be advertised using > either or > > both of ALPN or NPN. > > > > ``protocols`` should be a list of acceptable protocols in > the form > > of ``NextProtocol`` objects, such as ``[H2, HTTP1]``, > ordered by > > preference. The selection of the protocol will happen during > the > > handshake, and will use whatever protocol negotiation > mechanisms > > are available and supported by both peers. > > > > If the TLS implementation doesn't support protocol > negotiation, > > this method will raise ``NotImplementedError``. > > """ > > > > @abstractmethod > > def set_sni_callback(self, callback: > Optional[ServerNameCallback]) -> None: > > """ > > Register a callback function that will be called after the > TLS > > Client Hello handshake message has been received by the TLS > server > > when the TLS client specifies a server name indication. > > > > Only one callback can be set per ``Context``. If > ``callback`` is > > ``None`` then the callback is disabled. Calling this > function a > > subsequent time will disable the previously registered > callback. > > > > The ``callback`` function will be called with three > arguments: the > > first will be the ``TLSBufferObject`` for the connection; the > > second will be a string that represents the server name that > the > > client is intending to communicate (or ``None`` if the TLS > Client > > Hello does not contain a server name); and the third > argument will > > be the original ``Context``. The server name argument will > be the > > IDNA *decoded* server name. > > > > The ``callback`` must return ``None`` to allow negotiation to > > continue. Other return values signal errors. Attempting to > control > > what error is signaled by the underlying TLS implementation > is not > > specified in this API, but is up to the concrete > implementation to > > handle. > > """ > > > > @abstractmethod > > def set_version_range(self, lower_bound=None: > Optional[TLSVersion], > > upper_bound=None: Optional[TLSVersion]) -> > None: > > """ > > Set the minumum and maximum versions of TLS that should be > allowed > > on TLS connections made by this context. > > > > If present, ``lower_bound`` will set the lowest acceptable > TLS > > version. If present, ``upper_bound`` will set the highest > > acceptable TLS version. If either argument is ``None``, this > will > > leave that bound unchanged. > > """ > So, with ``` class TLSVersion(Enum): MINIMUM_SUPPORTED SSLv2 SSLv3 TLSv1 TLSv1_1 TLSv1_2 TLSv1_3 MAXIMUM_SUPPORTED ``` What are the (signed?) integer values?
_______________________________________________ Security-SIG mailing list Security-SIG@python.org https://mail.python.org/mailman/listinfo/security-sig