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

test_ssl failure when cacert.org CA cert in system keychain on OSX #59945

Closed
ronaldoussoren opened this issue Aug 20, 2012 · 12 comments
Closed
Labels
OS-mac stdlib Python modules in the Lib dir tests Tests in the Lib/test dir type-bug An unexpected behavior, bug, or error

Comments

@ronaldoussoren
Copy link
Contributor

BPO 15740
Nosy @ronaldoussoren, @pitrou, @ned-deily
Files
  • issue15740.txt
  • issue15740-2.txt
  • issue15740-3.txt
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = <Date 2012-08-22.12:39:36.807>
    created_at = <Date 2012-08-20.14:24:38.943>
    labels = ['OS-mac', 'tests', 'type-bug', 'library']
    title = 'test_ssl failure when cacert.org CA cert in system keychain on OSX'
    updated_at = <Date 2012-08-22.12:39:36.806>
    user = 'https://github.com/ronaldoussoren'

    bugs.python.org fields:

    activity = <Date 2012-08-22.12:39:36.806>
    actor = 'ronaldoussoren'
    assignee = 'none'
    closed = True
    closed_date = <Date 2012-08-22.12:39:36.807>
    closer = 'ronaldoussoren'
    components = ['Library (Lib)', 'macOS', 'Tests']
    creation = <Date 2012-08-20.14:24:38.943>
    creator = 'ronaldoussoren'
    dependencies = []
    files = ['26943', '26948', '26962']
    hgrepos = []
    issue_num = 15740
    keywords = []
    message_count = 12.0
    messages = ['168661', '168724', '168733', '168738', '168740', '168744', '168765', '168774', '168775', '168872', '168874', '168875']
    nosy_count = 3.0
    nosy_names = ['ronaldoussoren', 'pitrou', 'ned.deily']
    pr_nums = []
    priority = 'normal'
    resolution = 'wont fix'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue15740'
    versions = ['Python 2.7', 'Python 3.2', 'Python 3.3']

    @ronaldoussoren
    Copy link
    Contributor Author

    On my laptop (running OSX 10.8, but I have noticed the same on earlier OSX releases) test_ssl fails:

    ======================================================================
    FAIL: test_connect (test.test_ssl.NetworkedTests)
    ----------------------------------------------------------------------

    Traceback (most recent call last):
      File "/Users/ronald/Projects/python/rw/default/Lib/test/test_ssl.py", line 650, in test_connect
        s.connect, ("svn.python.org", 443))
    AssertionError: SSLError not raised by connect

    ======================================================================
    FAIL: test_connect_with_context (test.test_ssl.NetworkedTests)
    ----------------------------------------------------------------------

    Traceback (most recent call last):
      File "/Users/ronald/Projects/python/rw/default/Lib/test/test_ssl.py", line 743, in test_connect_with_context
        s.connect, ("svn.python.org", 443))
    AssertionError: SSLError not raised by connect

    ======================================================================
    FAIL: test_get_server_certificate (test.test_ssl.NetworkedTests)
    ----------------------------------------------------------------------

    Traceback (most recent call last):
      File "/Users/ronald/Projects/python/rw/default/Lib/test/test_ssl.py", line 848, in test_get_server_certificate
        _test_get_server_certificate('svn.python.org', 443, SVN_PYTHON_ORG_ROOT_CERT)
      File "/Users/ronald/Projects/python/rw/default/Lib/test/test_ssl.py", line 840, in _test_get_server_certificate
        self.fail("Got server certificate %s for %s:%s!" % (pem, host, port))
    AssertionError: Got server certificate -----BEGIN CERTIFICATE

    MIIEmTCCAoGgAwIBAgIDCyOkMA0GCSqGSIb3DQEBBQUAMHkxEDAOBgNVBAoTB1Jv
    b3QgQ0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEiMCAGA1UEAxMZ
    Q0EgQ2VydCBTaWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJARYSc3VwcG9y
    dEBjYWNlcnQub3JnMB4XDTExMTIyNTIxMzIxNVoXDTEzMTIyNDIxMzIxNVowGTEX
    MBUGA1UEAxMOc3ZuLnB5dGhvbi5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
    ggEKAoIBAQDM6un3wTW9+HVJ7KC+/GwL0KAxehug0tw2YoSSX+TGxLyr9AUtBHQk
    hCNWhRLewa0WMOY6hxIIQY1Hp6vreDiCbBehjVkEAydlKBzaAsgYCEbCC/ZaMzhv
    aaFAiLVeaxAKJsBGUJNz5hGgzd67A6SGz+XK7qDWig4NR5eFrsr3DvjyEM7txMiG
    gftGWLkadOuqUQsI20AykBGi+RxmrQIwqO2svGmje89DsWVILdP37PssM2zqRonh
    4fUKooei3L43tXbTdHayXc9NtFS7q8T4eUlyWaD+BtP80QQOQFFvi+qZpme9bmYI
    7YPX+e86lZtxAKM9nWrP93qc+2nS0MsHAgMBAAGjgYkwgYYwDAYDVR0TAQH/BAIw
    ADA0BgNVHSUELTArBggrBgEFBQcDAgYIKwYBBQUHAwEGCWCGSAGG+EIEAQYKKwYB
    BAGCNwoDAzALBgNVHQ8EBAMCBaAwMwYIKwYBBQUHAQEEJzAlMCMGCCsGAQUFBzAB
    hhdodHRwOi8vb2NzcC5jYWNlcnQub3JnLzANBgkqhkiG9w0BAQUFAAOCAgEAEsw6
    TMEXRn8ex1feaSNB5r2/aCLKE33ssGTp5HAyFo04YF2WaGK8HgjEg/fqrGUaSORw
    P1ikBNTAUiaKbRQtcIvQPg8Zk4lSiQZ7m6ePs4hKdFVKeOpykwQyTsm+NaGk4xtM
    Zk0XsWkzFntG676MT2FGvDCn0XhtdpAGJy59FXQ1mto9j99AvXpcl9Ja7tRYI/mI
    goq3Gu6lwIoYSnslOtIWgsj9Wog1Kug7zoGscxY6z2lk15wbQlQbXbdAbVW7RZry
    07eGwROLpE8tydRvvCbJp3P7FE+aAk1D3fQi09G0dUJWRmvBoFOVZCfHmGx23Mpz
    YTVgGP1bydjjzzhNAqaKctLf6g3UuUwsOJ1pso4Cr/00EDWG1JsRb4wtlpAEPSnb
    vjr/TqHMfefeQf4DmgWo1DutKhUBur5t+VukVCN1z44VtKeu8zaNaA3vR2Q+jArl
    YxIFGUTuBcDHBx5Zl0Wcauoe3IbIBckBk2+WOBXVAdj00a46XJ4OHesft63HVOLn
    vsKqAhwHPgsH0iTrgbO6ky0Xk573aJWz5wrlYin2FzHXsfJkA7U0wesrG4AFdeAm
    zICOAFz9bOhyi6t5c0whF6L0W6Gt4cW+tERG+CD++2svdh8JP9QgozoSKd9N33bg
    q5qGifkRs3lTJQGn2wDkgepX1vtshWgRXR9QTRw=
    -----END CERTIFICATE-----

     for svn.python.org:443!

    This machine has the cacert root certificate as a trusted key in the system keychain.

    This is using Apple's copy of OpenSSL, I haven't tested yet if the test failure is also present with the upstream edition of OpenSSL.

    The failure seems to occur because the test assumes that the OpenSSL library either won't load a CA list at all when ca_cert is not specified, or that the default CA list doesn't contain the cacert.org one.

    I can avoid the test failures by always specifying ca_certs in these tests, but point the argument to an empty file. That's probably not the right solution though, hence I haven't included this as a patch.

    @ronaldoussoren ronaldoussoren self-assigned this Aug 20, 2012
    @ronaldoussoren ronaldoussoren added stdlib Python modules in the Lib dir OS-mac tests Tests in the Lib/test dir labels Aug 20, 2012
    @ronaldoussoren ronaldoussoren removed their assignment Aug 20, 2012
    @pitrou
    Copy link
    Member

    pitrou commented Aug 21, 2012

    The failure seems to occur because the test assumes that the OpenSSL
    library either won't load a CA list at all when ca_cert is not
    specified, or that the default CA list doesn't contain the cacert.org one.

    Well, OpenSSL should not implicitly load a CA list when not asked to.
    If it does, it means Apple hacked their OpenSSL copy.
    (I am further surprised that Apple includes cacert by default in the trusted certificates, while mainstream browsers like Firefox don't)

    @ned-deily
    Copy link
    Member

    As Ronald is aware, there is also the issue that Apple has deprecated use of OpenSSL in OS X:

    "Although OpenSSL is commonly used in the open source community, OpenSSL does not provide a stable API from version to version. For this reason, although OS X provides OpenSSL libraries, the OpenSSL libraries in OS X are deprecated, and OpenSSL has never been provided as part of iOS. Use of the OS X OpenSSL libraries by applications is strongly discouraged.

    If your application depends on OpenSSL, you should compile OpenSSL yourself and statically link a known version of OpenSSL into your application."

    In OS X 10.7, for instance, OpenSSL is at 0.9.8r. I think the same is true for 10.8. We should probably bite the bullet here and do as Apple urges, that is, supply our own libssl 1.0.x for the python.org OS X installer builds.

    http://developer.apple.com/library/mac/#documentation/security/Conceptual/cryptoservices/GeneralPurposeCrypto/GeneralPurposeCrypto.html

    @ronaldoussoren
    Copy link
    Contributor Author

    What's rather annoying is that I cannot find OpenSSL on opensource.apple.com, which means we cannot check if they use patches add functionality that our users would like to have.

    One such feature is likely keychain integration (that is, use the CA roots from the user and system keychain instead of a CA root store in the file system). I'm not 100% sure that this functionality is actually present, but as _ssl automaticly finds a CA root certificate that I have added to the system keychain gives a pretty clear indication.

    BTW. It might be worthwhile to investigate if it would be possible to write a version of the _ssl extension that links with Apple frameworks (like CommonCrypto) instead of OpenSSL. There are two obvious reason why this might not work out: Apple's frameworks might not over all functionality needed to implement _ssl (and _hashlib, and the additional code adds maintenance overhead that could be too high.

    @ronaldoussoren
    Copy link
    Contributor Author

    Antoine: Apple almost certainly has hacked their copy of OpenSSL, they do so for other libraries (including python) as well.

    Apple does not ship CAcerts root certificate, I've added it to the System Keychain on my machine because I use a number of machines that use CAcert signed certificates.

    And I've found Apple's copy of the OpenSSL sources: <http://www.opensource.apple.com/source/OpenSSL/\>

    @ronaldoussoren
    Copy link
    Contributor Author

    More interesingly are the download archives for OpenSSL098, which is the openssl version that's used on newer OSX releases. Sadly enough the version used on OSX 10.8 is not present there (that seems to be OpenSSL098-47, the latest download is -35).

    Download link: <http://opensource.apple.com/tarballs/OpenSSL098/\>

    I've downloaded the most recent release from that link and based on a 5 minute glance at the code this does seem to integrate with the system keychain ("src/crypto/x509/x509_vfy_apple.c" in the source tee)

    And that code also pointed to a way to disable that functionality, and that resolves the test failure on my machine.

    Without workaround:

    $ ./python.exe -m test.regrtest  -uall test_ssl
    [1/1] test_ssl
    test test_ssl failed -- multiple errors occurred; run in verbose mode for details
    1 test failed:
        test_ssl

    With workaround:

    $ env OPENSSL_X509_TEA_DISABLE=1 ./python.exe -m test.regrtest  -uall test_ssl
    [1/1] test_ssl
    Resource 'ipv6.google.com' is not available
    Warning -- asyncore.socket_map was modified by test_ssl
    1 test altered the execution environment:
        test_ssl

    (And test.regrtest -v also shows that all tests passed)

    The attached (crufty) patch sets the environment variable during test_ssl.NetworkedTests and that also avoids the test failure. It might be useful to add this functionality to the test case (but less crufty, and with a comment that explains why this is done).

    @pitrou
    Copy link
    Member

    pitrou commented Aug 21, 2012

    The attached (crufty) patch sets the environment variable during
    test_ssl.NetworkedTests and that also avoids the test failure. It might
    be useful to add this functionality to the test case (but less crufty,
    and with a comment that explains why this is done).

    I would prefer it to be done only under OS X platforms.

    @ronaldoussoren
    Copy link
    Contributor Author

    Attached cleaner version of the test:

    • use self.addCleanup instead of a tearDown method
    • add comment that explains why the code is present
    • setUp method is only active on OSX

    @pitrou
    Copy link
    Member

    pitrou commented Aug 21, 2012

    Attached cleaner version of the test:

    • use self.addCleanup instead of a tearDown method
    • add comment that explains why the code is present
    • setUp method is only active on OSX

    Looks good to me, thank you.

    @ronaldoussoren
    Copy link
    Contributor Author

    This also affects 2.7, and the patch doesn't work there.

    It does work when I add the call to os.putenv at module scope before (before importing ssl), but I don't really like that.

    It is probably necessary to do it like this though, the code that checks if the keychain integration is enabled caches its results and which means my patch only works accidentally (based on the order tests happen to be run in).

    I've attached a 3th version of the patch that also works with 2.7 (that is, after manually applying the patch). I'm not too happy about it though, the module now changes the environment of the entire test suite (on OSX).

    Annoyingly the 3th version does *not* work with 'make test' for python 3.3 , even when I change os.environ. I haven't tried to debug that yet.

    I'm disabling the CAcert root key in my keychain for no to be able to test patches without running into this issue.

    @pitrou
    Copy link
    Member

    pitrou commented Aug 22, 2012

    Le mercredi 22 août 2012 à 11:57 +0000, Ronald Oussoren a écrit :

    I've attached a 3th version of the patch that also works with 2.7
    (that is, after manually applying the patch). I'm not too happy about
    it though, the module now changes the environment of the entire test
    suite (on OSX).

    This will fail if the ssl module has already been imported by another
    test.
    Given the workaround is so fragile, I would recommend skipping the test
    on OS X instead.

    @ronaldoussoren
    Copy link
    Contributor Author

    There is no need to unconditionally skip the test. The cacert.org root certificate is not present on most systems, I just happened to have imported it into my keychain.

    I've removed the cacert root from my keychain and test_ssl now passed without a patch.

    I agree that is it not worthwhile to pursue this further and will therefore close this issue as "wont fix".

    @ronaldoussoren ronaldoussoren added the type-bug An unexpected behavior, bug, or error label Aug 22, 2012
    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    OS-mac stdlib Python modules in the Lib dir tests Tests in the Lib/test dir type-bug An unexpected behavior, bug, or error
    Projects
    None yet
    Development

    No branches or pull requests

    3 participants