"""Current-user Windows capability protection; no browser profile crypto state.""" import base64 import ctypes import sys class Blob(ctypes.Structure): _fields_=[('size',ctypes.c_uint32),('data',ctypes.POINTER(ctypes.c_ubyte))] def convert(data,protect): crypt=ctypes.WinDLL('crypt32',use_last_error=True) kernel=ctypes.WinDLL('kernel32',use_last_error=True) allocation=(ctypes.c_ubyte*len(data)).from_buffer_copy(data) source=Blob(len(data),allocation);result=Blob() function=crypt.CryptProtectData if protect else crypt.CryptUnprotectData function.argtypes=[ctypes.POINTER(Blob),ctypes.c_void_p,ctypes.c_void_p,ctypes.c_void_p,ctypes.c_void_p,ctypes.c_uint32,ctypes.POINTER(Blob)] function.restype=ctypes.c_int # UI_FORBIDDEN; omit LOCAL_MACHINE so only the signed-in Windows user can decrypt. if not function(ctypes.byref(source),None,None,None,None,1,ctypes.byref(result)): raise ValueError('DPAPI rejected capability') kernel.LocalFree.argtypes=[ctypes.c_void_p];kernel.LocalFree.restype=ctypes.c_void_p try:return ctypes.string_at(result.data,result.size) finally:kernel.LocalFree(result.data) if __name__=='__main__': try: if sys.platform!='win32' or len(sys.argv)!=2 or sys.argv[1] not in ['protect','unprotect']: raise ValueError() data=sys.stdin.buffer.read(32769) if not data or len(data)>32768:raise ValueError() if sys.argv[1]=='protect':output=base64.b64encode(convert(data,True)) else:output=convert(base64.b64decode(data,validate=True),False) sys.stdout.buffer.write(output) except Exception: sys.stderr.write('Windows capability protection failed.\n');sys.exit(1)