Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bpo-31432: Clarify CERT_NONE/OPTIONAL/REQUIRED doc #3530

Merged
merged 2 commits into from
Jun 11, 2018

Conversation

tiran
Copy link
Member

@tiran tiran commented Sep 13, 2017

The documentation for CERT_NONE, CERT_OPTIONAL, and CERT_REQUIRED were
misleading and partly wrong. It fails to explain that OpenSSL behaves
differently in client and server mode. Also OpenSSL does validate the
cert chain everytime. With SSL_VERIFY_NONE a validation error is not
fatal in client mode and does not request a client cert in server mode.

Also discourage people from using CERT_OPTIONAL in client mode.

Signed-off-by: Christian Heimes christian@python.org

https://bugs.python.org/issue31432

@tiran
Copy link
Member Author

tiran commented Sep 13, 2017

Memo to me: drop PROTOCOL_TLS_CLIENT in 2.7 backport.

@tiran tiran force-pushed the bpo-31432-cert-doc branch from 58d89be to 0243bd5 Compare September 15, 2017 15:08
Modules/_ssl.c Outdated
@@ -3228,8 +3228,8 @@ set_check_hostname(PySSLContext *self, PyObject *arg, void *c)
if (check_hostname &&
SSL_CTX_get_verify_mode(self->ctx) == SSL_VERIFY_NONE) {
PyErr_SetString(PyExc_ValueError,
"check_hostname needs a SSL context with either "
"CERT_OPTIONAL or CERT_REQUIRED");
"check_hostname needs a SSLContext with "
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: should be an SSLContext

@tiran tiran force-pushed the bpo-31432-cert-doc branch from 0243bd5 to 2f4126a Compare September 15, 2017 15:17
@tiran tiran force-pushed the bpo-31432-cert-doc branch 2 times, most recently from 597b493 to 0f3916d Compare January 20, 2018 23:14
@tiran tiran force-pushed the bpo-31432-cert-doc branch from 0f3916d to 6dde39e Compare February 22, 2018 17:40
@tiran tiran requested a review from vadmium February 22, 2018 17:40
@tiran
Copy link
Member Author

tiran commented Feb 22, 2018

@vadmium Martin, you have helped me with documentation of PR #5259. Could you check this documentation, too?

are provided, validation will be attempted and an :class:`SSLError`
will be raised on failure.
parameter to :func:`wrap_socket`. In client mode, :const:`CERT_OPTIONAL`
has the same meaning as :const:`CERT_REQUIRED`. It is recommended to
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if “anonymous ciphers are enabled”, mentioned under https://docs.python.org/dev/library/ssl.html#verifying-certificates?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather not explain anonymous cipher suites and just remove them from the documentation completely. Anonymous cipher suites is a misleading term. They don't provide anonymity for the user but allow the server to stay anonymous by not providing any authentication. It's totally insecure and no longer supported in TLS 1.3 for a very good reason.

If a certificate is received from the other end, no attempt to validate it
is made.
parameter to :func:`wrap_socket`. Except for :const:`PROTOCOL_TLS_CLIENT`,
it is the default mode. With client-side sockets, just about any
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does cert_reqs default to if I call wrap_socket(..., ssl_version=PROTOCOL_TLS_CLIENT)? Judging by the signature and documentation for wrap_socket, CERT_NONE seems to be the default regardless of the protocol setting. If you are only talking about the default value for verify_mode after an SSLContext is constructed, I suggest to mention that under the entry for SSLContext.verify_mode, or the SSLContext constructor, instead of here. (Otherwise, maybe adjust the description of the top-level wrap_socket function.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For a moment I feared that you have discovered a security bug.

Thankfully the code is robust and doesn't allow you to use PROTOCOL_TLS_CLIENT with default arguments of wrap_socket and SSLSocket. Both ssl.wrap_socket(ssl_version=ssl.PROTOCOL_TLS_CLIENT) and ssl.SSLSocket(ssl_version=ssl.PROTOCOL_TLS_CLIENT) will both fail with error Cannot set verify_mode to CERT_NONE when check_hostname is enabled..

So the insecure default doesn't work here. I consider it a feature. :) I'm going to deprecate ssl.wrap_socket and ssl.SSLSocket() default constructor because they have more fundamental issues.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, now I realize that the PROTOCOL_TLS_CLIENT mode is newer than the old wrap_socket function. It was not clear that wrap_socket doesn’t support this new mode, but that is separate to what you are trying to do here.

@tiran tiran force-pushed the bpo-31432-cert-doc branch from 6dde39e to 7cb02cf Compare February 25, 2018 09:15
@tiran
Copy link
Member Author

tiran commented Feb 25, 2018

@vadmium I have removed the misleading note about anonymous ciphers.

@tiran tiran force-pushed the bpo-31432-cert-doc branch from 7cb02cf to 350506a Compare May 14, 2018 18:07
@willingc
Copy link
Contributor

Hi @vadmium, It looks like this is ready to be merged. Is there anything that prevents doing so at this point? Thanks.

tiran added 2 commits May 22, 2018 12:53
The documentation for CERT_NONE, CERT_OPTIONAL, and CERT_REQUIRED were
misleading and partly wrong. It fails to explain that OpenSSL behaves
differently in client and server mode. Also OpenSSL does validate the
cert chain everytime. With SSL_VERIFY_NONE a validation error is not
fatal in client mode and does not request a client cert in server mode.

Also discourage people from using CERT_OPTIONAL in client mode.

Signed-off-by: Christian Heimes <christian@python.org>
The documentation no longer mentions anonymous ciphers. They are totally
insecure and irrelevant for virtually all users. The documentation was
also wrong. For anonymous ciphers, CERT_NONE, CERT_OPTIONAL and
CERT_REQUIRED all behaved the same.

Internally, CERT_REQUIRED = SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT
but the last flag is ignored in client mode. When a anonymous cipher is
used, clients ignore missing server certs.

Signed-off-by: Christian Heimes <christian@python.org>
@tiran tiran force-pushed the bpo-31432-cert-doc branch from 350506a to 86aa7d2 Compare May 22, 2018 10:53
@ned-deily
Copy link
Member

@tiran, @vadmium I would prefer to merge this for 3.7.0. If I don't hear any objections in the next day or so, I will merge it.

@ned-deily ned-deily merged commit ef24b6c into python:master Jun 11, 2018
@miss-islington
Copy link
Contributor

Thanks @tiran for the PR, and @ned-deily for merging it 🌮🎉.. I'm working now to backport this PR to: 2.7, 3.6, 3.7.
🐍🍒⛏🤖

@bedevere-bot
Copy link

GH-7649 is a backport of this pull request to the 3.7 branch.

miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Jun 11, 2018
The documentation for CERT_NONE, CERT_OPTIONAL, and CERT_REQUIRED were
misleading and partly wrong. It fails to explain that OpenSSL behaves
differently in client and server mode. Also OpenSSL does validate the
cert chain everytime. With SSL_VERIFY_NONE a validation error is not
fatal in client mode and does not request a client cert in server mode.
Also discourage people from using CERT_OPTIONAL in client mode.
(cherry picked from commit ef24b6c)

Co-authored-by: Christian Heimes <christian@python.org>
@miss-islington
Copy link
Contributor

Sorry, @tiran and @ned-deily, I could not cleanly backport this to 3.6 due to a conflict.
Please backport using cherry_picker on command line.
cherry_picker ef24b6c54d40e7820456873a6eab6ef57d2bd0db 3.6

@miss-islington
Copy link
Contributor

Sorry, @tiran and @ned-deily, I could not cleanly backport this to 2.7 due to a conflict.
Please backport using cherry_picker on command line.
cherry_picker ef24b6c54d40e7820456873a6eab6ef57d2bd0db 2.7

ned-deily pushed a commit that referenced this pull request Jun 11, 2018
…H-7649)

The documentation for CERT_NONE, CERT_OPTIONAL, and CERT_REQUIRED were
misleading and partly wrong. It fails to explain that OpenSSL behaves
differently in client and server mode. Also OpenSSL does validate the
cert chain everytime. With SSL_VERIFY_NONE a validation error is not
fatal in client mode and does not request a client cert in server mode.
Also discourage people from using CERT_OPTIONAL in client mode.
(cherry picked from commit ef24b6c)

Co-authored-by: Christian Heimes <christian@python.org>
ned-deily pushed a commit to ned-deily/cpython that referenced this pull request Jun 12, 2018
The documentation for CERT_NONE, CERT_OPTIONAL, and CERT_REQUIRED were
misleading and partly wrong. It fails to explain that OpenSSL behaves
differently in client and server mode. Also OpenSSL does validate the
cert chain everytime. With SSL_VERIFY_NONE a validation error is not
fatal in client mode and does not request a client cert in server mode.
Also discourage people from using CERT_OPTIONAL in client mode.
@bedevere-bot
Copy link

GH-7652 is a backport of this pull request to the 3.6 branch.

ned-deily added a commit that referenced this pull request Jun 12, 2018
…H-7652)

The documentation for CERT_NONE, CERT_OPTIONAL, and CERT_REQUIRED were
misleading and partly wrong. It fails to explain that OpenSSL behaves
differently in client and server mode. Also OpenSSL does validate the
cert chain everytime. With SSL_VERIFY_NONE a validation error is not
fatal in client mode and does not request a client cert in server mode.
Also discourage people from using CERT_OPTIONAL in client mode.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs Documentation in the Doc dir
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants