Ejemplo n.º 1
0
    def import_cert(self, cert_data, machine_keyset=True,
                    store_name=STORE_NAME_MY):

        base64_cert_data = self._get_cert_base64(cert_data)

        cert_encoded = None
        store_handle = None
        cert_context_p = None

        try:
            cert_encoded_len = wintypes.DWORD()

            if not cryptoapi.CryptStringToBinaryW(
                    base64_cert_data, len(base64_cert_data),
                    cryptoapi.CRYPT_STRING_BASE64,
                    None, ctypes.byref(cert_encoded_len),
                    None, None):
                raise cryptoapi.CryptoAPIException()

            size = ctypes.c_size_t(cert_encoded_len.value)
            cert_encoded = ctypes.cast(malloc(size),
                                       ctypes.POINTER(wintypes.BYTE))

            if not cryptoapi.CryptStringToBinaryW(
                    base64_cert_data, len(base64_cert_data),
                    cryptoapi.CRYPT_STRING_BASE64,
                    cert_encoded, ctypes.byref(cert_encoded_len),
                    None, None):
                raise cryptoapi.CryptoAPIException()

            if machine_keyset:
                flags = cryptoapi.CERT_SYSTEM_STORE_LOCAL_MACHINE
            else:
                flags = cryptoapi.CERT_SYSTEM_STORE_CURRENT_USER

            store_handle = cryptoapi.CertOpenStore(
                cryptoapi.CERT_STORE_PROV_SYSTEM, 0, 0, flags,
                six.text_type(store_name))
            if not store_handle:
                raise cryptoapi.CryptoAPIException()

            cert_context_p = ctypes.POINTER(cryptoapi.CERT_CONTEXT)()

            if not cryptoapi.CertAddEncodedCertificateToStore(
                    store_handle,
                    cryptoapi.X509_ASN_ENCODING |
                    cryptoapi.PKCS_7_ASN_ENCODING,
                    cert_encoded, cert_encoded_len,
                    cryptoapi.CERT_STORE_ADD_REPLACE_EXISTING,
                    ctypes.byref(cert_context_p)):
                raise cryptoapi.CryptoAPIException()

            # Get the UPN (1.3.6.1.4.1.311.20.2.3 OID) from the
            # certificate subject alt name
            upn = None
            upn_len = cryptoapi.CertGetNameString(
                cert_context_p,
                cryptoapi.CERT_NAME_UPN_TYPE, 0,
                None, None, 0)
            if upn_len > 1:
                upn_ar = ctypes.create_unicode_buffer(upn_len)
                if cryptoapi.CertGetNameString(
                        cert_context_p,
                        cryptoapi.CERT_NAME_UPN_TYPE,
                        0, None, upn_ar, upn_len) != upn_len:
                    raise cryptoapi.CryptoAPIException()
                upn = upn_ar.value

            thumbprint = self._get_cert_thumprint(cert_context_p)
            return thumbprint, upn
        finally:
            if cert_context_p:
                cryptoapi.CertFreeCertificateContext(cert_context_p)
            if store_handle:
                cryptoapi.CertCloseStore(store_handle, 0)
            if cert_encoded:
                free(cert_encoded)
Ejemplo n.º 2
0
    def decode_pkcs7_base64_blob(self,
                                 data,
                                 thumbprint_str,
                                 machine_keyset=True,
                                 store_name=STORE_NAME_MY):
        base64_data = data.replace('\r', '').replace('\n', '')
        store_handle = None
        cert_context_p = None

        try:
            data_encoded_len = wintypes.DWORD()

            if not cryptoapi.CryptStringToBinaryW(
                    base64_data, len(base64_data),
                    cryptoapi.CRYPT_STRING_BASE64, None,
                    ctypes.byref(data_encoded_len), None, None):
                raise cryptoapi.CryptoAPIException()

            data_encoded = ctypes.cast(
                ctypes.create_string_buffer(data_encoded_len.value),
                ctypes.POINTER(wintypes.BYTE))

            if not cryptoapi.CryptStringToBinaryW(
                    base64_data, len(base64_data),
                    cryptoapi.CRYPT_STRING_BASE64, data_encoded,
                    ctypes.byref(data_encoded_len), None, None):
                raise cryptoapi.CryptoAPIException()

            store_handle = cryptoapi.CertOpenStore(
                cryptoapi.CERT_STORE_PROV_MEMORY,
                cryptoapi.X509_ASN_ENCODING | cryptoapi.PKCS_7_ASN_ENCODING,
                None, cryptoapi.CERT_STORE_CREATE_NEW_FLAG, None)
            if not store_handle:
                raise cryptoapi.CryptoAPIException()

            cert_context_p = self._find_certificate_in_store(
                thumbprint_str, machine_keyset, store_name)

            if not cryptoapi.CertAddCertificateLinkToStore(
                    store_handle, cert_context_p, cryptoapi.CERT_STORE_ADD_NEW,
                    None):
                raise cryptoapi.CryptoAPIException()

            para = cryptoapi.CRYPT_DECRYPT_MESSAGE_PARA()
            para.cbSize = ctypes.sizeof(cryptoapi.CRYPT_DECRYPT_MESSAGE_PARA)
            para.dwMsgAndCertEncodingType = (cryptoapi.X509_ASN_ENCODING
                                             | cryptoapi.PKCS_7_ASN_ENCODING)
            para.cCertStore = 1
            para.rghCertStore = ctypes.pointer(wintypes.HANDLE(store_handle))
            para.dwFlags = cryptoapi.CRYPT_SILENT

            data_decoded_len = wintypes.DWORD()
            if not cryptoapi.CryptDecryptMessage(
                    ctypes.byref(para), data_encoded, data_encoded_len, None,
                    ctypes.byref(data_decoded_len), None):
                raise cryptoapi.CryptoAPIException()

            data_decoded_buf = ctypes.create_string_buffer(
                data_decoded_len.value)
            data_decoded = ctypes.cast(data_decoded_buf,
                                       ctypes.POINTER(wintypes.BYTE))

            if not cryptoapi.CryptDecryptMessage(
                    ctypes.pointer(para), data_encoded, data_encoded_len,
                    data_decoded, ctypes.byref(data_decoded_len), None):
                raise cryptoapi.CryptoAPIException()

            return bytes(data_decoded_buf)
        finally:
            if cert_context_p:
                cryptoapi.CertFreeCertificateContext(cert_context_p)
            if store_handle:
                cryptoapi.CertCloseStore(store_handle, 0)