working on crypto.certificate.CryptObject

This commit is contained in:
Clement Rouault
2017-01-13 18:07:56 +01:00
parent ae02d9e916
commit 8743883068
3 changed files with 99 additions and 1 deletions
+83 -1
View File
@@ -10,6 +10,88 @@ from windows.crypto.helper import ECRYPT_DATA_BLOB
CRYPT_OBJECT_FORMAT_TYPE = [
CERT_QUERY_OBJECT_FILE,
CERT_QUERY_OBJECT_BLOB,
CERT_QUERY_CONTENT_CERT,
CERT_QUERY_CONTENT_CTL,
CERT_QUERY_CONTENT_CRL,
CERT_QUERY_CONTENT_SERIALIZED_STORE,
CERT_QUERY_CONTENT_SERIALIZED_CERT,
CERT_QUERY_CONTENT_SERIALIZED_CTL,
CERT_QUERY_CONTENT_SERIALIZED_CRL,
CERT_QUERY_CONTENT_PKCS7_SIGNED,
CERT_QUERY_CONTENT_PKCS7_UNSIGNED,
CERT_QUERY_CONTENT_PKCS7_SIGNED_EMBED,
CERT_QUERY_CONTENT_PKCS10,
CERT_QUERY_CONTENT_PFX,
CERT_QUERY_CONTENT_CERT_PAIR,
CERT_QUERY_CONTENT_PFX_AND_LOAD
]
CRYPT_OBJECT_FORMAT_TYPE_DICT = {x:x for x in CRYPT_OBJECT_FORMAT_TYPE}
## Move CryptObject to new .py ?
class CryptObject(object):
MSG_PARAM_KNOW_TYPES = {CMSG_SIGNER_INFO_PARAM: CMSG_SIGNER_INFO,
CMSG_SIGNER_COUNT_PARAM: DWORD}
def __init__(self, filename, content_type=CERT_QUERY_CONTENT_FLAG_ALL):
# No other API than filename for now..
self.filename = filename
dwEncoding = DWORD()
dwContentType = DWORD()
dwFormatType = DWORD()
hStore = PVOID()
hMsg = PVOID()
winproxy.CryptQueryObject(CERT_QUERY_OBJECT_FILE,
LPWSTR(filename),
content_type,
CERT_QUERY_FORMAT_FLAG_BINARY,
0,
dwEncoding,
dwContentType,
dwFormatType,
hStore,
hMsg,
None)
self.hstore = hStore
self.hmsg = hMsg
self.encoding = dwEncoding
self.content_type = CRYPT_OBJECT_FORMAT_TYPE_DICT.get(dwContentType.value, dwContentType)
def msg_get_param(self, param_type):
signer_info = DWORD()
winproxy.CryptMsgGetParam(self.hmsg, param_type, 0, None, signer_info)
buffer = ctypes.c_buffer(signer_info.value)
winproxy.CryptMsgGetParam(self.hmsg, param_type, 0, buffer, signer_info)
if param_type in self.MSG_PARAM_KNOW_TYPES:
buffer = self.MSG_PARAM_KNOW_TYPES[param_type].from_buffer_copy(buffer)
return buffer
def get_nb_signer(self):
return self.msg_get_param(CMSG_SIGNER_COUNT_PARAM).value
def get_signer_data(self):
return self.msg_get_param(CMSG_SIGNER_INFO_PARAM)
def get_signer_certificate(self):
data = self.get_signer_data()
cert_info = CERT_INFO()
cert_info.Issuer = data.Issuer
cert_info.SerialNumber = data.SerialNumber
rawcertcontext = winproxy.CertFindCertificateInStore(self.hstore, self.encoding, 0, CERT_FIND_SUBJECT_CERT, byref(cert_info), None)
#return rawcertcontext
return CertificatContext(rawcertcontext[0])
def __repr__(self):
return '<{0} "{1}" content_type={2}>'.format(type(self).__name__, self.filename, self.content_type)
class EHCERTSTORE(HCERTSTORE):
# def __str__(self):
@@ -146,5 +228,5 @@ class CertficateChain(object):
def to_list(self):
res = []
for i in range(self.chain.rgpChain[0][0].cElement):
res.append(CertificatContext(self.chain.rgpChain[0][0].rgpElement[i][0].pCertContext))
res.append(CertificatContext(self.chain.rgpChain[0][0].rgpElement[i][0].pCertContext[0]))
return res
+14
View File
@@ -1122,6 +1122,20 @@ def CryptEncodeObjectEx(dwCertEncodingType, lpszStructType, pvStructInfo, dwFlag
def CertCreateCertificateContext(dwCertEncodingType, pbCertEncoded, cbCertEncoded):
return CertCreateCertificateContext.ctypes_function(dwCertEncodingType, pbCertEncoded, cbCertEncoded)
@Crypt32Proxy('CryptQueryObject')
def CryptQueryObject(dwObjectType, pvObject, dwExpectedContentTypeFlags, dwExpectedFormatTypeFlags, dwFlags, pdwMsgAndCertEncodingType, pdwContentType, pdwFormatType, phCertStore, phMsg, ppvContext):
return CryptQueryObject.ctypes_function(dwObjectType, pvObject, dwExpectedContentTypeFlags, dwExpectedFormatTypeFlags, dwFlags, pdwMsgAndCertEncodingType, pdwContentType, pdwFormatType, phCertStore, phMsg, ppvContext)
@Crypt32Proxy('CryptMsgGetParam')
def CryptMsgGetParam(hCryptMsg, dwParamType, dwIndex, pvData, pcbData):
return CryptMsgGetParam.ctypes_function(hCryptMsg, dwParamType, dwIndex, pvData, pcbData)
@Crypt32Proxy('CryptDecodeObject')
def CryptDecodeObject(dwCertEncodingType, lpszStructType, pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo):
return CryptDecodeObject.ctypes_function(dwCertEncodingType, lpszStructType, pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo)
# ## User32 stuff ## #
EnumWindows = TransparentUser32Proxy('EnumWindows')
+2
View File
@@ -125,6 +125,7 @@ def get_catalog_for_filename(filename):
while t is not None:
t = winproxy.CryptCATAdminEnumCatalogFromHash(ctx, hash, len(hash), 0, ctypes.byref(HCATINFO(t)))
# Todo: how to handle multiple catalog ?
winproxy.CryptCATAdminReleaseCatalogContext(ctx, t, 0)
winproxy.CryptCATAdminReleaseContext(ctx, 0)
return tname
@@ -145,6 +146,7 @@ def get_file_hash(filename):
# The volume for a file has been externally altered so that the opened file is no longer valid.
# (returned for empty file)
return None
raise
return buffer