[pypy-commit] pypy py3.5: Implement ssl.enum_crls() for win32

arigo pypy.commits at gmail.com
Mon Apr 23 12:15:24 EDT 2018


Author: Armin Rigo <arigo at tunes.org>
Branch: py3.5
Changeset: r94429:2a637a86bcba
Date: 2018-04-23 18:02 +0200
http://bitbucket.org/pypy/pypy/changeset/2a637a86bcba/

Log:	Implement ssl.enum_crls() for win32

diff --git a/lib_pypy/_cffi_ssl/_cffi_src/openssl/pypy_win32_extra.py b/lib_pypy/_cffi_ssl/_cffi_src/openssl/pypy_win32_extra.py
--- a/lib_pypy/_cffi_ssl/_cffi_src/openssl/pypy_win32_extra.py
+++ b/lib_pypy/_cffi_ssl/_cffi_src/openssl/pypy_win32_extra.py
@@ -12,12 +12,21 @@
 TYPES = """
 typedef ... *HCERTSTORE;
 typedef ... *HCRYPTPROV_LEGACY;
+
 typedef struct {
     DWORD      dwCertEncodingType;
     BYTE       *pbCertEncoded;
     DWORD      cbCertEncoded;
     ...;
 } CERT_CONTEXT, *PCCERT_CONTEXT;
+
+typedef struct {
+    DWORD      dwCertEncodingType;
+    BYTE       *pbCrlEncoded;
+    DWORD      cbCrlEncoded;
+    ...;
+} CRL_CONTEXT, *PCCRL_CONTEXT;
+
 typedef struct {
     DWORD cUsageIdentifier;
     LPSTR *rgpszUsageIdentifier;
@@ -40,6 +49,9 @@
 BOOL WINAPI CertFreeCertificateContext(
          PCCERT_CONTEXT pCertContext
 );
+BOOL WINAPI CertFreeCRLContext(
+         PCCRL_CONTEXT pCrlContext
+);
 BOOL WINAPI CertCloseStore(
          HCERTSTORE hCertStore,
          DWORD      dwFlags
@@ -50,6 +62,10 @@
          PCERT_ENHKEY_USAGE pUsage,
          DWORD              *pcbUsage
 );
+PCCRL_CONTEXT WINAPI CertEnumCRLsInStore(
+         HCERTSTORE    hCertStore,
+         PCCRL_CONTEXT pPrevCrlContext
+);
 """
 
 MACROS = """
diff --git a/lib_pypy/_cffi_ssl/_stdssl/__init__.py b/lib_pypy/_cffi_ssl/_stdssl/__init__.py
--- a/lib_pypy/_cffi_ssl/_stdssl/__init__.py
+++ b/lib_pypy/_cffi_ssl/_stdssl/__init__.py
@@ -24,7 +24,7 @@
 from enum import IntEnum as _IntEnum
 
 if sys.platform == 'win32':
-    from _cffi_ssl._stdssl.win32_extra import enum_certificates
+    from _cffi_ssl._stdssl.win32_extra import enum_certificates, enum_crls
     HAVE_POLL = False
 else:
     from select import poll, POLLIN, POLLOUT
diff --git a/lib_pypy/_cffi_ssl/_stdssl/win32_extra.py b/lib_pypy/_cffi_ssl/_stdssl/win32_extra.py
--- a/lib_pypy/_cffi_ssl/_stdssl/win32_extra.py
+++ b/lib_pypy/_cffi_ssl/_stdssl/win32_extra.py
@@ -18,20 +18,55 @@
     
     result = []
     pCertCtx = ffi.NULL
-    while True:
-        pCertCtx = lib.CertEnumCertificatesInStore(hStore, pCertCtx)
-        if pCertCtx == ffi.NULL:
-            break
-        cert = ffi.buffer(pCertCtx.pbCertEncoded, pCertCtx.cbCertEncoded)[:]
-        enc = certEncodingType(pCertCtx.dwCertEncodingType)
-        keyusage = parseKeyUsage(pCertCtx, lib.CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG)
-        if keyusage is True:
-            keyusage = parseKeyUsage(pCertCtx, lib.CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG)
-        result.append((cert, enc, keyusage))
+    try:
+        while True:
+            pCertCtx = lib.CertEnumCertificatesInStore(hStore, pCertCtx)
+            if pCertCtx == ffi.NULL:
+                break
+            cert = ffi.buffer(pCertCtx.pbCertEncoded, pCertCtx.cbCertEncoded)[:]
+            enc = certEncodingType(pCertCtx.dwCertEncodingType)
+            keyusage = parseKeyUsage(pCertCtx, lib.CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG)
+            if keyusage is True:
+                keyusage = parseKeyUsage(pCertCtx, lib.CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG)
+            result.append((cert, enc, keyusage))
+    finally:
+        if pCertCtx != ffi.NULL:
+            lib.CertFreeCertificateContext(pCertCtx)
+        if not lib.CertCloseStore(hStore, 0):
+            # This error case might shadow another exception.
+            raise WindowsError(*ffi.getwinerror())
+    return result
 
-    if pCertCtx != ffi.NULL:
-        lib.CertFreeCertificateContext(pCertCtx)
-    lib.CertCloseStore(hStore, 0)
+
+def enum_crls(store_name):
+    """Retrieve CRLs from Windows' cert store.
+
+store_name may be one of 'CA', 'ROOT' or 'MY'.  The system may provide
+more cert storages, too.  The function returns a list of (bytes,
+encoding_type) tuples.  The encoding_type flag can be interpreted with
+X509_ASN_ENCODING or PKCS_7_ASN_ENCODING."""
+    hStore = lib.CertOpenStore(lib.CERT_STORE_PROV_SYSTEM_A, 0, ffi.NULL,
+                               lib.CERT_STORE_READONLY_FLAG | lib.CERT_SYSTEM_STORE_LOCAL_MACHINE,
+                               bytes(store_name, "ascii"))
+    if hStore == ffi.NULL:
+        raise WindowsError(*ffi.getwinerror())
+
+    result = []
+    pCrlCtx = ffi.NULL
+    try:
+        while True:
+            pCrlCtx = lib.CertEnumCRLsInStore(hStore, pCrlCtx)
+            if pCrlCtx == ffi.NULL:
+                break
+            crl = ffi.buffer(pCrlCtx.pbCrlEncoded, pCrlCtx.cbCrlEncoded)[:]
+            enc = certEncodingType(pCrlCtx.dwCertEncodingType)
+            result.append((crl, enc))
+    finally:
+        if pCrlCtx != ffi.NULL:
+            lib.CertFreeCRLContext(pCrlCtx)
+        if not lib.CertCloseStore(hStore, 0):
+            # This error case might shadow another exception.
+            raise WindowsError(*ffi.getwinerror())
     return result
 
 


More information about the pypy-commit mailing list