📄 cryptlibconverter.py
字号:
import sysimport osimport statimport re#Helper Functions#==========================================================================def parseEnumContents(enumContents, nameSpace, debugString): enumPattern = re.compile(r"(CRYPT_[\w_]*)\s*(=.*?)?(\Z|,|(?=/))", re.DOTALL) # %1 [= %2][,] commentPattern = re.compile(r"\s*/\*(.*)\*/") # /* %1 */ counter = 0 #Keep track of the implicit enum value enumTuples = [] #Build a list of (key, val, comment) tuples, one for each enum value #Find the next "enum value" enumMatch = enumPattern.search(enumContents) while enumMatch: #Extract the key and RHS value rawKey, rawVal = enumMatch.groups()[:-1] key = rawKey.rstrip() if not key.startswith("CRYPT_"): raise "enum'd value doesn't start with CRYPT_ "+key key = key.replace("CRYPT_", "") #Evaluate the RHS (if it exists) to get the value if rawVal: rhs = rawVal[1:].strip().replace("CRYPT_", "") val = eval(rhs, nameSpace) #Otherwise the value is the implicit counter else: val = counter #Extract the comment commentMatch = commentPattern.match(enumContents, enumMatch.end()) if commentMatch: rawComment = commentMatch.group(1) comment = rawComment.strip() else: comment = "" #Collect all the parsed values into a tuple enumTuple = (key, str(val), comment) #if comment: # print debugString+ ":" + " Parsed Element %s = %s /* %s */" % enumTuple #else: # print debugString+ ":" + " Parsed Element %s = %s" % enumTuple[:-1] #raw_input() nameSpace[key] = val #Add new enum value into namespace counter = val + 1 #Increment implicit enum value #Accumulate the parsed (key, val, comment) tuples enumTuples.append(enumTuple) #Get next enum value enumMatch = enumPattern.search(enumContents, enumMatch.end()) return enumTuples#Parses a string of function parameters into a list of ParamStructclass ParamStruct: def __init__(self): self.type = "" self.isPtr = 0 self.isOut = 0 self.category = "" self.name = "" self.rawIndex = 0 # The index of this param in the initial, raw cryptlib header def __str__(self): return str( (self.type, self.isPtr, self.category, self.name, self.rawIndex) )def parseFunctionParams(functionParams): paramStructs = [] functionParams = functionParams.replace("\n", "") #Make one big line functionParamsList = [e.strip() for e in functionParams.split(",")] #Break into a list of params index = 0 for e in functionParamsList: pieces = e.split(" ") #Separate each param into component pieces, ie ["C_IN", "CRYPT_ALGO_TYPE", "cryptAlgo"] p = ParamStruct() if len(pieces)==1 and pieces[0]=="void": continue elif len(pieces)==3: if pieces[0] == "C_OUT": p.isOut = 1 if pieces[1] == "C_STR": p.type = "char" p.name = pieces[2] p.isPtr = 1 else: p.type = pieces[1] p.name = pieces[2] p.isPtr = 0 elif len(pieces)==4: #Ie ["C_OUT", "CRYPT_CONTEXT", "C_PTR", "cryptContext"] if pieces[0] == "C_OUT": p.isOut = 1 p.type = pieces[1] if pieces[2] == "C_PTR": p.isPtr = 1 else: raise "Expecting C_PTR in parseFunctionParams" p.name = pieces[3] else: raise "parsing error in parseFunctionParams" if p.type in enumTypes: p.category = "enumType" elif p.type in intTypes: p.category = "intType" elif p.type in structTypes: p.category = "structType" elif p.type in rawTypes: p.category = "rawType" else: raise "unknown type error is parseFunctionParams" p.rawIndex = index index += 1 paramStructs.append(p) #for p in paramStructs: # print p.__dict__ #raw_input() return paramStructs#Takes a string containing a JNI function parameters prototype list, and a list of ParamStructs#And injects names into the string and returns itdef expandFunctionPrototype(functionPrototype, newParamStructs): functionPrototype = functionPrototype.replace("\n", "") #Make one big line paramPrototypesList = [e.strip() for e in functionPrototype.split(",")] #Break into a list of params paramNamesList = ["env", "cryptClass"] + [e.name for e in newParamStructs] newFunctionParams = "" for (p1, p2) in zip(paramPrototypesList, paramNamesList): newFunctionParams += p1 + " " + p2 + ", " newFunctionParams = newFunctionParams[:-2] return newFunctionParams#Main#=========================================================================#Execution starts here...#=========================================================================if len(sys.argv) != 4: print "cryptlibConverter.py <inFile> <outDir> <language>" sys.exit()inFile = sys.argv[1]outDir = sys.argv[2]language = sys.argv[3]if not os.path.exists(outDir): print "Making output directory..." os.mkdir(outDir)if not language in ("java", "python", "net"): print "only java, python, and net are supported!" sys.exit()if language == "java": #ENUM IDIOM #typedefEnumTemplate = "public static class %(typedefName)s\n{public int getValue(){return m_value;}private %(typedefName)s(int value){m_value = value;}int m_value;}" #typedefEnumElementTemplate = "public static final %(typedefName)s %(name)-NPADs = new %(typedefName)s(%(value)-VPADs);" #ENUMs as ints typedefEnumTemplate = "// %(typedefName)s" typedefEnumElementTemplate = "public static final int %(name)-NPADs = %(value)-VPADs;" typedefEnumElementTemplateComment = typedefEnumElementTemplate + " // %(comment)s" simpleEnumElementTemplate = "public static final int %(name)-NPADs = %(value)-VPADs;" simpleEnumElementTemplateComment = simpleEnumElementTemplate + " // %(comment)s" defineNPad = "40" defineVPad = "4" defineTemplate = simpleEnumElementTemplate defineTemplateComment = simpleEnumElementTemplateComment exceptionPrefix = """package cryptlib;public class CryptException extends Exception{ private int m_status; private String m_message; public CryptException(int status) { m_status = status; String prefix = Integer.toString(status) + ": ";""" exceptionPostfix = """\ m_message = prefix + "Unknown Exception ?!?!"; } public int getStatus() { return m_status; } public String getMessage() { return m_message; }};""" exceptionTemplate = """\ if (m_status == crypt.%(name)s) { m_message = prefix + "%(comment)s"; return; }""" cryptQueryInfoString = """package cryptlib;public class CRYPT_QUERY_INFO{ public String algoName; public int blockSize; public int minKeySize; public int keySize; public int maxKeySize; public CRYPT_QUERY_INFO(String newAlgoName, int newBlockSize, int newMinKeySize, int newKeySize, int newMaxKeySize) { algoName = newAlgoName; blockSize = newBlockSize; minKeySize = newMinKeySize; keySize = newKeySize; maxKeySize = newMaxKeySize; }};""" cryptObjectInfoString = """package cryptlib;public class CRYPT_OBJECT_INFO{ public int objectType; public int cryptAlgo; public int cryptMode; public int hashAlgo; public byte[] salt; public CRYPT_OBJECT_INFO(int newObjectType, int newCryptAlgo, int newCryptMode, int newHashAlgo, byte[] newSalt) { objectType = newObjectType; cryptAlgo = newCryptAlgo; cryptMode = newCryptMode; hashAlgo = newHashAlgo; salt = newSalt; }};""" addFunctionWrappers = 1 wholeFunctionDeclaration = None functionDeclaration = "public static native " returnIntDeclaration = "int " returnVoidDeclaration = "void " paramsPrefix = "(" paramsPostfix = ") throws CryptException;" paramWhiteSpace = "\t\t\t\t\t\t" paramVoidPtrTemplate = "java.nio.ByteBuffer %(name)s,\n" addFunctionAlternate = 1 paramVoidPtrAlternate = ("java.nio.ByteBuffer", "byte[]") paramCharPtrTemplate = "String %(name)s,\n" paramIntTemplate = "int %(name)s,\n" paramIntTypeTemplate = "int %(name)s, // %(type)s\n" #wrapperLengthTemplate = "%s.capacity(), " #wrapperStringLengthTemplate = "%s.length(), " wrapperLengthTemplate = "%(1)s == null ? 0 : %(1)s.capacity(), " wrapperStringLengthTemplate = "%(1)s == null ? 0 : %(1)s.getBytes().length, " wrapperStringReplace = ("java.nio.ByteBuffer", "String") wrapperStringTemplate = '%(1)s == null ? null : %(1)s.getBytes()' #ENUM IDIOM #paramEnumTypeTemplate = "%(type)s %(name)s,\n" #ENUMs as ints paramEnumTypeTemplate = "int %(name)s, // %(type)s\n" commentPrefix = "//" classPrefix = "package cryptlib;\n\nimport java.nio.*;\n\npublic class crypt\n{\n" classPostfix = "\n};" sFuncs = None sInts = Noneelif language == "python": typedefEnumTemplate = "" #typedefEnumElementTemplate = "%(name)-NPADs = %(value)-VPADs" typedefEnumElementTemplate = """\ v = Py_BuildValue("i", %(value)s); PyDict_SetItemString(moduleDict, "CRYPT_%(name)s", v); Py_DECREF(v);""" typedefEnumElementTemplateComment = typedefEnumElementTemplate + " /* %(comment)s */" simpleEnumElementTemplate = typedefEnumElementTemplate simpleEnumElementTemplateComment = typedefEnumElementTemplateComment defineNPad = "40" defineVPad = "4" defineTemplate = typedefEnumElementTemplate defineTemplateComment = typedefEnumElementTemplateComment exceptionPrefix = "" exceptionPostfix = "" exceptionTemplate = """\ else if (status == CRYPT_%(name)s) o = Py_BuildValue("(is)", CRYPT_%(name)s, "%(comment)s");""" addFunctionWrappers = 0 wholeFunctionDeclaration = """\static PyObject* python_crypt%s(PyObject* self, PyObject* args){}""" moduleFunctionEntry = "\t{ \"crypt%s\", python_crypt%s, METH_VARARGS }, " pyBeforeExceptions = r"""#include <Python.h>#include "../cryptlib.h"static PyObject* cryptHandleClass;static PyObject* cryptQueryInfoClass;static PyObject* cryptObjectInfoClass;static PyObject *CryptException;static int getPointerWrite(PyObject* objPtr, unsigned char** bytesPtrPtr, int* lengthPtr){ if (objPtr == Py_None) { *bytesPtrPtr = NULL; *lengthPtr = 0; return 1; } /*See if it's an array object*/ if (PyObject_AsWriteBuffer(objPtr, bytesPtrPtr, lengthPtr) == -1) return 0; return 1;}static int getPointerRead(PyObject* objPtr, unsigned char** bytesPtrPtr, int* lengthPtr){ if (objPtr == Py_None) { *bytesPtrPtr = NULL; *lengthPtr = 0; return 1; } /*See if it's an array object*/ if (PyObject_AsWriteBuffer(objPtr, bytesPtrPtr, lengthPtr) == -1) { PyErr_Clear(); /*See if it's a string object*/ /*This returns the length excluding the NULL if it's a string, which is what we want*/ if (PyObject_AsCharBuffer(objPtr, bytesPtrPtr, lengthPtr) == -1) return 0; } return 1;}static int getPointerReadNoLength(PyObject* objPtr, unsigned char** bytesPtrPtr){ int length; return getPointerRead(objPtr, bytesPtrPtr, &length);}static int getPointerWriteCheckIndices(PyObject* objPtr, unsigned char** bytesPtrPtr, int* lengthPtr){ int checkLength = *lengthPtr; if (getPointerWrite(objPtr, bytesPtrPtr, lengthPtr) == 0) return 0; //If sequence is non-NULL and too short... if (*bytesPtrPtr && (*lengthPtr < checkLength)) { PyErr_SetString(PyExc_IndexError, "A sequence passed to cryptlib was too small"); return 0; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -