132 lines
4.0 KiB
Python
132 lines
4.0 KiB
Python
from ctypes import FormatError
|
|
from ctypes import windll, c_void_p, byref, create_string_buffer, c_int
|
|
import struct
|
|
|
|
from wincrypto.constants import HP_ALGID, HP_HASHSIZE, KP_KEYLEN, KP_ALGID, CRYPT_EXPORTABLE
|
|
|
|
|
|
PROV_RSA_FULL = 1
|
|
PROV_RSA_AES = 24
|
|
|
|
|
|
def assert_success(success):
|
|
if not success:
|
|
raise AssertionError(FormatError())
|
|
|
|
|
|
def CryptAcquireContext():
|
|
hprov = c_void_p()
|
|
success = windll.advapi32.CryptAcquireContextA(byref(hprov), 0, 0, PROV_RSA_AES, 0)
|
|
assert_success(success)
|
|
return hprov
|
|
|
|
|
|
def CryptReleaseContext(hprov):
|
|
success = windll.advapi32.CryptReleaseContext(hprov, 0)
|
|
assert_success(success)
|
|
|
|
|
|
def CryptImportKey(hprov, keyblob, hPubKey=0):
|
|
hkey = c_void_p()
|
|
success = windll.advapi32.CryptImportKey(hprov, keyblob, len(keyblob), hPubKey, 0, byref(hkey))
|
|
assert_success(success)
|
|
return hkey
|
|
|
|
|
|
def CryptExportKey(hkey, hexpkey, blobType):
|
|
# determine output buffer length
|
|
bdatalen = c_int(0)
|
|
success = windll.advapi32.CryptExportKey(hkey, hexpkey, blobType, 0, 0, byref(bdatalen))
|
|
assert_success(success)
|
|
|
|
# export key
|
|
bdata = create_string_buffer(b'', bdatalen.value)
|
|
success = windll.advapi32.CryptExportKey(hkey, hexpkey, blobType, 0, bdata, byref(bdatalen))
|
|
assert_success(success)
|
|
return bdata.raw[:bdatalen.value]
|
|
|
|
|
|
def CryptDestroyKey(hkey):
|
|
success = windll.advapi32.CryptDestroyKey(hkey)
|
|
assert_success(success)
|
|
|
|
|
|
def CryptDecrypt(hkey, encrypted_data):
|
|
bdata = create_string_buffer(encrypted_data)
|
|
bdatalen = c_int(len(encrypted_data))
|
|
success = windll.advapi32.CryptDecrypt(hkey, 0, 1, 0, bdata, byref(bdatalen))
|
|
assert_success(success)
|
|
return bdata.raw[:bdatalen.value]
|
|
|
|
|
|
def CryptEncrypt(hkey, plain_data):
|
|
# determine output buffer length
|
|
bdatalen_test = c_int(len(plain_data))
|
|
success = windll.advapi32.CryptEncrypt(hkey, 0, 1, 0, 0, byref(bdatalen_test), len(plain_data))
|
|
assert_success(success)
|
|
out_buf_len = bdatalen_test.value
|
|
|
|
# encrypt data
|
|
bdata = create_string_buffer(plain_data, out_buf_len)
|
|
bdatalen = c_int(len(plain_data))
|
|
success = windll.advapi32.CryptEncrypt(hkey, 0, 1, 0, bdata, byref(bdatalen), out_buf_len)
|
|
assert_success(success)
|
|
return bdata.raw[:bdatalen.value]
|
|
|
|
|
|
def CryptGetKeyParam(hkey, dwparam):
|
|
# determine output buffer length
|
|
bdatalen = c_int(0)
|
|
success = windll.advapi32.CryptGetKeyParam(hkey, dwparam, 0, byref(bdatalen), 0)
|
|
assert_success(success)
|
|
|
|
# get hash param
|
|
bdata = create_string_buffer(b'', bdatalen.value)
|
|
success = windll.advapi32.CryptGetKeyParam(hkey, dwparam, bdata, byref(bdatalen), 0)
|
|
assert_success(success)
|
|
result = bdata.raw[:bdatalen.value]
|
|
if dwparam in [KP_KEYLEN, KP_ALGID]:
|
|
result = struct.unpack('I', result)[0]
|
|
return result
|
|
|
|
|
|
def CryptCreateHash(hProv, Algid):
|
|
hCryptHash = c_void_p()
|
|
success = windll.advapi32.CryptCreateHash(hProv, Algid, 0, 0, byref(hCryptHash))
|
|
assert_success(success)
|
|
return hCryptHash
|
|
|
|
|
|
def CryptHashData(hHash, data):
|
|
bdata = create_string_buffer(data)
|
|
dwdatalen = c_int(len(data))
|
|
success = windll.advapi32.CryptHashData(hHash, bdata, dwdatalen, 0)
|
|
assert_success(success)
|
|
|
|
|
|
def CryptGetHashParam(hHash, dwParam):
|
|
# determine output buffer length
|
|
bdatalen = c_int(0)
|
|
success = windll.advapi32.CryptGetHashParam(hHash, dwParam, 0, byref(bdatalen), 0)
|
|
assert_success(success)
|
|
|
|
# get hash param
|
|
bdata = create_string_buffer(b'', bdatalen.value)
|
|
success = windll.advapi32.CryptGetHashParam(hHash, dwParam, bdata, byref(bdatalen), 0)
|
|
assert_success(success)
|
|
result = bdata.raw[:bdatalen.value]
|
|
if dwParam in [HP_ALGID, HP_HASHSIZE]:
|
|
result = struct.unpack('I', result)[0]
|
|
return result
|
|
|
|
|
|
def CryptDestroyHash(hCryptHash):
|
|
success = windll.advapi32.CryptDestroyHash(hCryptHash)
|
|
assert_success(success)
|
|
|
|
|
|
def CryptDeriveKey(hProv, Algid, hBaseData):
|
|
hkey = c_void_p()
|
|
success = windll.advapi32.CryptDeriveKey(hProv, Algid, hBaseData, CRYPT_EXPORTABLE, byref(hkey))
|
|
assert_success(success)
|
|
return hkey |