[pypy-commit] pypy stdlib-2.7.9: More fields in decode_certificate.

amauryfa noreply at buildbot.pypy.org
Sun Feb 1 19:34:02 CET 2015


Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: stdlib-2.7.9
Changeset: r75628:60293e8655ee
Date: 2015-01-31 19:08 +0100
http://bitbucket.org/pypy/pypy/changeset/60293e8655ee/

Log:	More fields in decode_certificate.

diff --git a/pypy/module/_ssl/interp_ssl.py b/pypy/module/_ssl/interp_ssl.py
--- a/pypy/module/_ssl/interp_ssl.py
+++ b/pypy/module/_ssl/interp_ssl.py
@@ -636,7 +636,7 @@
     space.setitem(w_retval, space.wrap("issuer"), w_issuer)
 
     space.setitem(w_retval, space.wrap("version"),
-                  space.wrap(libssl_X509_get_version(certificate)))
+                  space.wrap(libssl_X509_get_version(certificate) + 1))
 
     biobuf = libssl_BIO_new(libssl_BIO_s_mem())
     try:
@@ -680,6 +680,11 @@
     if w_alt_names is not space.w_None:
         space.setitem(w_retval, space.wrap("subjectAltName"), w_alt_names)
 
+    # CDP (CRL distribution points)
+    w_cdp = _get_crl_dp(space, certificate)
+    if not space.is_none(w_cdp):
+        space.setitem(w_retval, space.wrap("crlDistributionPoints"), w_cdp)
+
     return w_retval
 
 
@@ -828,6 +833,29 @@
     return space.newtuple([w_name, w_value])
 
 
+def _get_crl_dp(space, certificate):
+    # Calls x509v3_cache_extensions and sets up crldp
+    libssl_X509_check_ca(certificate)
+    dps = certificate[0].c_crldp
+    if not dps:
+        return None
+
+    cdp_w = []
+    for i in range(libssl_sk_DIST_POINT_num(dps)):
+        dp = libssl_sk_DIST_POINT_value(dps, i)
+        gns = libssl_pypy_DIST_POINT_fullname(dp)
+
+        for j in range(libssl_sk_GENERAL_NAME_num(gns)):
+            name = libssl_sk_GENERAL_NAME_value(gns, j)
+            gntype = intmask(name[0].c_type)
+            if gntype != GEN_URI:
+                continue
+            uri = libssl_pypy_GENERAL_NAME_uri(name)
+            length = intmask(uri.c_length)
+            s_uri = rffi.charpsize2str(uri.c_data, length)
+            cdp_w.append(space.wrap(s_uri))
+    return space.newtuple(cdp_w[:])
+
 def checkwait(space, w_sock, writing):
     """If the socket has a timeout, do a select()/poll() on the socket.
     The argument writing indicates the direction.
diff --git a/pypy/module/_ssl/test/test_ssl.py b/pypy/module/_ssl/test/test_ssl.py
--- a/pypy/module/_ssl/test/test_ssl.py
+++ b/pypy/module/_ssl/test/test_ssl.py
@@ -340,6 +340,9 @@
         assert len(certs) == 1
         print(certs)
         assert len(certs[0]['issuer']) == 4
+        assert certs[0]['version'] == 3
+        assert certs[0]['crlDistributionPoints'] == (
+            'https://www.cacert.org/revoke.crl',)
 
     def test_load_dh_params(self):
         import _ssl
diff --git a/rpython/rlib/ropenssl.py b/rpython/rlib/ropenssl.py
--- a/rpython/rlib/ropenssl.py
+++ b/rpython/rlib/ropenssl.py
@@ -38,7 +38,9 @@
         # Unnamed structures are not supported by rffi_platform.
         # So we replace an attribute access with a macro call.
         '#define pypy_GENERAL_NAME_dirn(name) (name->d.dirn)',
+        '#define pypy_GENERAL_NAME_uri(name) (name->d.uniformResourceIdentifier)',
         '#define pypy_X509_OBJECT_data_x509(obj) (obj->data.x509)',
+        '#define pypy_DIST_POINT_fullname(obj) (obj->distpoint->name.fullname)',
     ],
 )
 
@@ -48,12 +50,14 @@
           include_dir='inc32', library_dir='out32'),
      ])
 
-X509 = rffi.COpaquePtr('X509')
 ASN1_STRING = lltype.Ptr(lltype.ForwardReference())
+ASN1_IA5STRING = ASN1_STRING
 ASN1_ITEM = rffi.COpaquePtr('ASN1_ITEM')
 X509_NAME = rffi.COpaquePtr('X509_NAME')
 X509_VERIFY_PARAM = rffi.COpaquePtr('X509_VERIFY_PARAM')
 stack_st_X509_OBJECT = rffi.COpaquePtr('struct stack_st_X509_OBJECT')
+DIST_POINT = rffi.COpaquePtr('DIST_POINT')
+stack_st_DIST_POINT = rffi.COpaquePtr('struct stack_st_DIST_POINT')
 DH = rffi.COpaquePtr('DH')
 
 class CConfigBootstrap:
@@ -138,6 +142,10 @@
     OBJ_NAME_TYPE_MD_METH = rffi_platform.ConstantInteger(
         "OBJ_NAME_TYPE_MD_METH")
 
+    X509_st = rffi_platform.Struct(
+        'struct x509_st',
+        [('crldp', stack_st_DIST_POINT)])
+
     # Some structures, with only the fields used in the _ssl module
     X509_name_entry_st = rffi_platform.Struct('struct X509_name_entry_st',
                                               [('set', rffi.INT)])
@@ -193,6 +201,7 @@
 SSL_CIPHER = rffi.COpaquePtr('SSL_CIPHER')
 SSL = rffi.COpaquePtr('SSL')
 BIO = rffi.COpaquePtr('BIO')
+X509 = rffi.CArrayPtr(X509_st)
 X509_NAME_ENTRY = rffi.CArrayPtr(X509_name_entry_st)
 X509_EXTENSION = rffi.CArrayPtr(X509_extension_st)
 X509_STORE = rffi.CArrayPtr(x509_store_st)
@@ -341,10 +350,18 @@
              X509_OBJECT, macro=True)
 ssl_external('pypy_X509_OBJECT_data_x509', [X509_OBJECT], X509,
              macro=True)
+ssl_external('sk_DIST_POINT_num', [stack_st_DIST_POINT], rffi.INT,
+             macro=True)
+ssl_external('sk_DIST_POINT_value', [stack_st_DIST_POINT, rffi.INT], DIST_POINT,
+             macro=True)
+ssl_external('pypy_DIST_POINT_fullname', [DIST_POINT], GENERAL_NAMES,
+             macro=True)
 
 ssl_external('GENERAL_NAME_print', [BIO, GENERAL_NAME], rffi.INT)
 ssl_external('pypy_GENERAL_NAME_dirn', [GENERAL_NAME], X509_NAME,
              macro=True)
+ssl_external('pypy_GENERAL_NAME_uri', [GENERAL_NAME], ASN1_IA5STRING,
+             macro=True)
 
 ssl_external('SSL_get_current_cipher', [SSL], SSL_CIPHER)
 ssl_external('SSL_CIPHER_get_name', [SSL_CIPHER], rffi.CCHARP)


More information about the pypy-commit mailing list