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

ssl.create_default_context() throws: "ssl.SSLError: [X509] unknown error (_ssl.c:4035)" #108721

Open
2 tasks done
bh1428 opened this issue Aug 31, 2023 · 8 comments
Open
2 tasks done
Labels
topic-SSL type-bug An unexpected behavior, bug, or error

Comments

@bh1428
Copy link

bh1428 commented Aug 31, 2023

Bug report

Checklist

  • I am confident this is a bug in CPython, not a bug in a third-party project
  • I have searched the CPython issue tracker,
    and am confident this bug has not been reported before

CPython versions tested on:

3.11

Operating systems tested on:

Windows

Output from running 'python -VV' on the command line:

Python 3.11.5 (tags/v3.11.5:cce6ba9, Aug 24 2023, 14:38:34) [MSC v.1936 64 bit (AMD64)]

A clear and concise description of the bug:

In one of my systems, this triggers an exception in Python 3.11.5 and works fine in Python 3.11.4:

import ssl
ssl.create_default_context()

The exception is:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Program Files\Python311\Lib\ssl.py", line 775, in create_default_context
    context.load_default_certs(purpose)
  File "C:\Program Files\Python311\Lib\ssl.py", line 596, in load_default_certs
    self._load_windows_store_certs(storename, purpose)
  File "C:\Program Files\Python311\Lib\ssl.py", line 588, in _load_windows_store_certs
    self.load_verify_locations(cadata=certs)
ssl.SSLError: [X509] unknown error (_ssl.c:4035)

The cause is a couple of TFS certificates in the Windows "CA" store:
image

If I remove one of these certificates (doesn't matter which one, I have tested both by removing, reimporting, etc.), the issue goes away.

It looks like commit 77e0919 is causing the issue. I have created a custom build of main with lines 670-673 of Modules/_ssl.c commented:

//                if (ERR_GET_LIB(e) == ERR_LIB_SSL &&
//                        ERR_GET_REASON(e) == SSL_R_CERTIFICATE_VERIFY_FAILED) {
//                    type = state->PySSLCertVerificationErrorObject;
//                }

When using this custom build (and the two certificates in the store), the issue does not occur.

Attached you'll find a zip with the two certificates (in case anyone is wondering, they are from a sandbox which is no longer in use) and a more elaborate example which finds out which certificates cause an issue by testing them one at a time (originally I had three certificates).

TFS_certs.zip

@bh1428 bh1428 added the type-bug An unexpected behavior, bug, or error label Aug 31, 2023
@AlexWaygood
Copy link
Member

It looks like commit 77e0919 is causing the issue.

Cc. @pablogsal @Yhg1s

@terryjreedy
Copy link
Member

terryjreedy commented Aug 31, 2023

The fact that 3.11.5 now raises an exception is not necessarily a bug. 77e0919 fixed a bug of not raising when appropriate. The claim is that the fix also raises when it should not.

@bh1428
Copy link
Author

bh1428 commented Aug 31, 2023

...The claim is that the fix also raises when it should not.

Indeed, thank you for the addition. As far as I can see there is nothing wrong with the certificates and if only one is present everything works as expected. Something seems to be handled differently by OpenSSL when two (or more) of these certificates are present (which may have been always the case) and that is now caught.

@pablogsal
Copy link
Member

Something has to be wrong with these certificates because the new code path is only triggered when there is an error and the error is that the cert could not be verified:

if (ERR_GET_LIB(e) == ERR_LIB_SSL &&                       ERR_GET_REASON(e) == SSL_R_CERTIFICATE_VERIFY_FAILED)                  

Unfortunately I am awaiting surgery in my hand this week and I cannot take a look at this. @ambv could you take a look if you have sone time?

In particular is unclear to me how this code is causing the problem when the code only triggers when OpenSSL tells us that there is an error and that the reason is a failure to verify a certificate.

@bh1428
Copy link
Author

bh1428 commented Aug 31, 2023

Initially I thought there must be something wrong with the certificates as well. I have to admit I don't know everything about X509 certificates but I cannot find an error.

The only thing I noticed is: they are created within a couple of minutes of each other and the error only occurs when BOTH certificates are present. Individually, when only one is present (doesn't matter which one) everything is working fine.

@bh1428
Copy link
Author

bh1428 commented Sep 1, 2023

The last comment from @pablogsal made me think and re-test things. Please ignore my comment about commit 77e0919, the issue is NOT caused by that commit. I'm sorry, my apologies, I didn't doublecheck everything properly.

These are working as expected (do not have this issue):

  • commit 3edcf74: main (I used this one for my initial test build)
  • commit 63bcd91: 3.12.0rc1

So the latest (pre-release) versions do not have this issue at the moment.

Commit 6193f78 is still okay:

PS C:\projects\cpython> git log -1
commit 6193f783d02190a66f287b3a36c187a9323dcc2b (HEAD -> Branch_6193f783)
Author: Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Date:   Mon Jul 17 01:15:52 2023 -0700

    [3.11] gh-106780: Add __match_args__ to tutorial example (GH-106784) (#106820)

    Add Point definition with this attribute before example
    that needs it.
    (cherry picked from commit 7aa89e505d893cd5e6f33b84d66e5fa769089931)

    Co-authored-by: Terry Jan Reedy <tjreedy@udel.edu>
PS C:\projects\cpython> .\python.bat -c "import ssl; ssl.create_default_context()"
Running Debug|x64 interpreter...

The next commit 263d8aa after commit 6193f78 is the first with the issue:

PS C:\projects\cpython> git log -1
commit 263d8aa017bd6d858aa9488154bc160fa7249a9e (HEAD -> Branch_263d8aa0)
Author: Zachary Ware <zach@python.org>
Date:   Mon Jul 17 12:07:52 2023 -0500

    [3.11] gh-99079: Update Windows build to use OpenSSL 3.0.9 (GH-106649) (GH-106761)

    Co-authored-by: Steve Dower <steve.dower@python.org>
PS C:\projects\cpython> .\python.bat -c "import ssl; ssl.create_default_context()"
Running Debug|x64 interpreter...
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "C:\projects\cpython\Lib\ssl.py", line 775, in create_default_context
    context.load_default_certs(purpose)
  File "C:\projects\cpython\Lib\ssl.py", line 596, in load_default_certs
    self._load_windows_store_certs(storename, purpose)
  File "C:\projects\cpython\Lib\ssl.py", line 588, in _load_windows_store_certs
    self.load_verify_locations(cadata=certs)
ssl.SSLError: [X509] unknown error (_ssl.c:4030)

So... I was wrong, in hindsight commit 263d8aa seems to introduce this issue.

@bh1428
Copy link
Author

bh1428 commented Sep 14, 2023

Did some further investigation and when I apply the changes from gh-100372 (manually) to Modules/_ssl.c (in 3.11.5) and recompile the issue goes away.

So... the fix for this issue seems to be gh-100372 which is in main and 3.12.0rc2 but not in 3.11.5.

@pablogsal: my apologies if this is a stupid question, but... what is the proper procedure to get gh-100372 into 3.11 as well?

@pablogsal
Copy link
Member

You should request a backport in the PR (I don't have the context for that PR but I think @Yhg1s would know if it makes sense to backport)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic-SSL type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

4 participants