Printing x509.get_issuer().get_components causes an exception

Bug #314814 reported by Markus Kettunen
2
Affects Status Importance Assigned to Milestone
pyOpenSSL
Fix Released
Undecided
Unassigned

Bug Description

The server is using a self signed certificate and the client does not trust it (loading certificate commented out). Thus the handshake will fail as it should.

But in addition, if VerifyCallback prints x509.get_issuer().get_components, or if the function is called, it causes another exception ('asn1 encoding routines', 'a2d_ASN1_OBJECT', 'first num too large'). This doesn't happen if the handshake succeeds.

You can use for example x509.get_issuer().commonName but not .get_components.

I'm using
Python 2.6.1 (r261:67515, Jan 7 2009, 15:48:16)
[GCC 4.2.4 (Ubuntu 4.2.4-1ubuntu3)] on linux2
<module 'OpenSSL.version' from '/usr/local/lib/python2.6/site-packages/pyOpenSSL-0.8-py2.6-linux-i686.egg/OpenSSL/version.pyc'>

After creating the self signed server certificate at cert/server.pem (and possibly copying to cert/ca.pem) I call python server.py in one terminal and python client.py in another.

Source code attached.

Revision history for this message
Markus Kettunen (makegho-blobtrox) wrote :
description: updated
Revision history for this message
Markus Kettunen (makegho-blobtrox) wrote :
Revision history for this message
Markus Kettunen (makegho-blobtrox) wrote :
description: updated
Revision history for this message
rick_dean (rick-fdd) wrote :

I have seen this bug as well. Sometime the failure has a different message of

python: Modules/gcmodule.c:261: update_refs: Assertion `gc->gc.gc_refs != 0' failed.

but I think it's only after an exception. I also see seg faults.

Python 2.5.2 (r252:60911, Sep 30 2008, 15:41:38)
[GCC 4.3.2 20080917 (Red Hat 4.3.2-4)] on linux2
openssl-0.9.8g-12.fc10.i686

Revision history for this message
rick_dean (rick-fdd) wrote :

My seg faults were a result of debugging code I added while investigating
the problem.

Revision history for this message
rick_dean (rick-fdd) wrote :

The attached one line patch to test_ssl.py tries to
print the common name of the certificate's subject in the verify_cb()
but causes python to assert/abort for me with...

python: Modules/gcmodule.c:261: update_refs: Assertion `gc->gc.gc_refs != 0' failed.

This page http://arctrix.com/nas/python/gc/ has an excellent description
of gc_refs, although not the common correction for this failure.
This page https://www.cca-forum.org/bugs/babel/issue397 suggests
this type of problem can be caused by an extra Py_DECREF().

Revision history for this message
rick_dean (rick-fdd) wrote :

lp:~rick-fdd/pyopenssl/actual_socket_test

Here is a new test case which is just
like MemoryBIOTests.do_connect(), but with
an actual socket. I wrote it to exonerate
bio_read() and bio_write().
The crashes are different, but still
possible by examining cert in verify_cb().

Please don't wait for this bug to be solved
before commiting this test case. It doesn't
add the problem code to verify_cb()

This branch also contains a small update
to the LATEX doc of WantReadError.

Revision history for this message
rick_dean (rick-fdd) wrote :

Here are more unit tests for verify_cb(). The failing ones are
commented out, and need to be resolved to resolve this bug.
lp:~rick-fdd/pyopenssl/verify_cb_tests

(It took over 7 minutes to push this branch.)

Revision history for this message
Jean-Paul Calderone (exarkun) wrote :

I tracked down at least part of the problem to the error reporting behavior of a2d_ASN1_OBJECT, invoked indirectly by crypto_x509Name_getattr, by way of OBJ_txt2nid (and various other intermediaries).

Despite OBJ_txt2nid returning NID_undef to indicate that the given NID identifier is not recognized, the lower level a2d_ASN1_OBJECT is also pushing errors onto the thread local error queue. I believe the proper fix is to flush the error queue in crypto_X509Name_getattr if NID_undef is returned.

Revision history for this message
Jean-Paul Calderone (exarkun) wrote :

Ah, and I think the other part of the problem, the failed assertion, is due to the use of error_queue_to_list() in the Py_DECREF macro in flush_error_queue. I thought there was a bug report for that, but I don't see it. Maybe we talked about face to face at PyCon. Or perhaps on some mailing list.

Anyhow, taking that function call out of that macro fixed that part of the problem for me.

Changed in pyopenssl:
status: New → Fix Committed
Changed in pyopenssl:
milestone: none → 0.10
Changed in pyopenssl:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.