11 enumPattern = re.compile(
r"(CRYPT_[\w_]*)\s*(=.*?)?(\Z|,|(?=/))", re.DOTALL)
12 commentPattern = re.compile(
r"\s*/\*(.*)\*/")
17 enumMatch = enumPattern.search(enumContents)
21 rawKey, rawVal = enumMatch.groups()[:-1]
24 if not key.startswith(
"CRYPT_"):
25 raise "enum'd value doesn't start with CRYPT_ "+key
26 key = key.replace(
"CRYPT_",
"")
30 rhs = rawVal[1:].strip().replace(
"CRYPT_",
"")
31 val = eval(rhs, nameSpace)
37 commentMatch = commentPattern.match(enumContents, enumMatch.end())
39 rawComment = commentMatch.group(1)
40 comment = rawComment.strip()
45 enumTuple = (key, str(val), comment)
57 enumTuples.append(enumTuple)
60 enumMatch = enumPattern.search(enumContents, enumMatch.end())
78 functionParams = functionParams.replace(
"\n",
"")
79 functionParamsList = [e.strip()
for e
in functionParams.split(
",")]
81 for e
in functionParamsList:
84 if len(pieces)==1
and pieces[0]==
"void":
87 if pieces[0] ==
"C_OUT":
89 if pieces[0] ==
"C_OUT_OPT":
91 if pieces[1] ==
"C_STR":
100 if pieces[0] ==
"C_OUT":
102 if pieces[0] ==
"C_OUT_OPT":
105 if pieces[2] ==
"C_PTR":
108 raise "Expecting C_PTR in parseFunctionParams"
111 raise "parsing error in parseFunctionParams"
112 if p.type
in enumTypes:
113 p.category =
"enumType"
114 elif p.type
in intTypes:
115 p.category =
"intType"
116 elif p.type
in structTypes:
117 p.category =
"structType"
118 elif p.type
in rawTypes:
119 p.category =
"rawType"
121 raise "unknown type error is parseFunctionParams"
124 paramStructs.append(p)
133 functionPrototype = functionPrototype.replace(
"\n",
"")
134 paramPrototypesList = [e.strip()
for e
in functionPrototype.split(
",")]
135 paramNamesList = [
"env",
"cryptClass"] + [e.name
for e
in newParamStructs]
136 newFunctionParams =
""
137 for (p1, p2)
in zip(paramPrototypesList, paramNamesList):
138 newFunctionParams += p1 +
" " + p2 +
", "
139 newFunctionParams = newFunctionParams[:-2]
140 return newFunctionParams
151 if len(sys.argv) != 4:
152 print "cryptlibConverter.py <inFile> <outDir> <language>"
157 language = sys.argv[3]
159 if not os.path.exists(outDir):
160 print "Making output directory..."
163 if not language
in (
"java",
"python",
"net"):
164 print "only java, python, and net are supported!"
167 if language ==
"java":
172 typedefEnumTemplate =
"// %(typedefName)s"
173 typedefEnumElementTemplate =
"public static final int %(name)-NPADs = %(value)-VPADs;"
175 typedefEnumElementTemplateComment = typedefEnumElementTemplate +
" // %(comment)s"
176 simpleEnumElementTemplate =
"public static final int %(name)-NPADs = %(value)-VPADs;"
177 simpleEnumElementTemplateComment = simpleEnumElementTemplate +
" // %(comment)s"
180 defineTemplate = simpleEnumElementTemplate
181 defineTemplateComment = simpleEnumElementTemplateComment
182 exceptionPrefix =
"""
185 public class CryptException extends Exception
187 private int m_status;
188 private String m_message;
189 public CryptException(int status)
192 String prefix = Integer.toString(status) + ": ";
195 exceptionPostfix =
"""\
196 m_message = prefix + "Unknown Exception ?!?!";
199 public int getStatus()
204 public String getMessage()
209 exceptionTemplate =
"""\
210 if (m_status == crypt.%(name)s) {
211 m_message = prefix + "%(comment)s";
214 cryptQueryInfoString =
"""
217 public class CRYPT_QUERY_INFO
219 public String algoName;
220 public int blockSize;
221 public int minKeySize;
223 public int maxKeySize;
225 public CRYPT_QUERY_INFO(String newAlgoName, int newBlockSize, int newMinKeySize, int newKeySize, int newMaxKeySize)
227 algoName = newAlgoName;
228 blockSize = newBlockSize;
229 minKeySize = newMinKeySize;
230 keySize = newKeySize;
231 maxKeySize = newMaxKeySize;
234 cryptObjectInfoString =
"""
237 public class CRYPT_OBJECT_INFO
239 public int objectType;
240 public int cryptAlgo;
241 public int cryptMode;
245 public CRYPT_OBJECT_INFO(int newObjectType, int newCryptAlgo, int newCryptMode, int newHashAlgo, byte[] newSalt)
247 objectType = newObjectType;
248 cryptAlgo = newCryptAlgo;
249 cryptMode = newCryptMode;
250 hashAlgo = newHashAlgo;
254 addFunctionWrappers = 1
255 wholeFunctionDeclaration =
None
256 functionDeclaration =
"public static native "
257 returnIntDeclaration =
"int "
258 returnVoidDeclaration =
"void "
260 paramsPostfix =
") throws CryptException;"
261 paramWhiteSpace =
"\t\t\t\t\t\t"
262 paramVoidPtrTemplate =
"java.nio.ByteBuffer %(name)s,\n"
263 addFunctionAlternate = 1
264 paramVoidPtrAlternate = (
"java.nio.ByteBuffer",
"byte[]")
265 paramCharPtrTemplate =
"String %(name)s,\n"
266 paramIntTemplate =
"int %(name)s,\n"
267 paramIntTypeTemplate =
"int %(name)s, // %(type)s\n"
270 wrapperLengthTemplate =
"%(1)s == null ? 0 : %(1)s.capacity(), "
271 wrapperStringLengthTemplate =
"%(1)s == null ? 0 : %(1)s.getBytes().length, "
272 wrapperStringReplace = (
"java.nio.ByteBuffer",
"String")
273 wrapperStringTemplate =
'%(1)s == null ? null : %(1)s.getBytes()'
277 paramEnumTypeTemplate =
"int %(name)s, // %(type)s\n"
279 classPrefix =
"package cryptlib;\n\nimport java.nio.*;\n\npublic class crypt\n{\n"
280 classPostfix =
"\n};"
283 elif language ==
"python":
284 typedefEnumTemplate =
""
286 typedefEnumElementTemplate =
"""\
288 v = Py_BuildValue("i", %(value)s);
289 PyDict_SetItemString(moduleDict, "CRYPT_%(name)s", v);
291 typedefEnumElementTemplateComment = typedefEnumElementTemplate +
" /* %(comment)s */"
292 simpleEnumElementTemplate = typedefEnumElementTemplate
293 simpleEnumElementTemplateComment = typedefEnumElementTemplateComment
296 defineTemplate = typedefEnumElementTemplate
297 defineTemplateComment = typedefEnumElementTemplateComment
299 exceptionPostfix =
""
300 exceptionTemplate =
"""\
301 else if (status == CRYPT_%(name)s)
302 o = Py_BuildValue("(is)", CRYPT_%(name)s, "%(comment)s");
304 addFunctionWrappers = 0
305 wholeFunctionDeclaration =
"""\
306 static PyObject* python_crypt%s(PyObject* self, PyObject* args)
310 moduleFunctionEntry =
"\t{ \"crypt%s\", python_crypt%s, METH_VARARGS }, "
311 pyBeforeExceptions =
r"""
313 #include "../cryptlib.h"
316 static PyObject* cryptHandleClass;
317 static PyObject* cryptQueryInfoClass;
318 static PyObject* cryptObjectInfoClass;
319 static PyObject *CryptException;
321 static int getPointerWrite(PyObject* objPtr, unsigned char** bytesPtrPtr, int* lengthPtr)
323 if (objPtr == Py_None)
332 /*See if it's an array object*/
333 if (PyObject_AsWriteBuffer(objPtr, (void **)bytesPtrPtr, &size) == -1)
339 static int getPointerRead(PyObject* objPtr, unsigned char** bytesPtrPtr, int* lengthPtr)
341 if (objPtr == Py_None)
350 /*See if it's an array object*/
351 if (PyObject_AsWriteBuffer(objPtr, (void **)bytesPtrPtr, &size) == -1)
354 /*See if it's a string object*/
355 /*This returns the length excluding the NULL if it's a string,
356 which is what we want*/
357 if (PyObject_AsCharBuffer(objPtr, (const char **)bytesPtrPtr, &size) == -1)
364 static int getPointerReadNoLength(PyObject* objPtr, unsigned char** bytesPtrPtr)
367 return getPointerRead(objPtr, bytesPtrPtr, &length);
370 static int getPointerWriteCheckIndices(PyObject* objPtr, unsigned char** bytesPtrPtr, int* lengthPtr)
372 int checkLength = *lengthPtr;
374 if (getPointerWrite(objPtr, bytesPtrPtr, lengthPtr) == 0)
377 //If sequence is non-NULL and too short...
378 if (*bytesPtrPtr && (*lengthPtr < checkLength))
380 PyErr_SetString(PyExc_IndexError, "A sequence passed to cryptlib was too small");
386 static int getPointerReadString(PyObject* objPtr, char** charPtrPtr)
388 Py_ssize_t length = 0;
391 if (objPtr == Py_None)
397 /*See if it's a string or a buffer object*/
398 if (PyObject_AsCharBuffer(objPtr, charPtrPtr, &length) == -1)
400 /*See if it's an array*/
402 if (PyObject_AsWriteBuffer(objPtr, charPtrPtr, &length) == -1)
405 /*This code isn't necessary for a string, but it is for arrays and buffers,
406 so we do it always anyway, since the PyObject_AsCharBuffer apparently doesn't
407 guarantee us null-terminated data, and this way releasePointerString() doesn't
408 have to differentiate */
409 newPtr = malloc(length+1);
415 memcpy(newPtr, *charPtrPtr, length);
417 *charPtrPtr = newPtr;
421 static void releasePointer(PyObject* objPtr, unsigned char* bytesPtr)
425 static void releasePointerString(PyObject* objPtr, char* charPtr)
430 static PyObject* processStatus(int status)
434 /* If an error has already occurred, ignore the status and just fall through */
435 if (PyErr_Occurred())
438 if (status >= CRYPT_OK)
439 return(Py_BuildValue(""));
442 PyErr_SetObject(CryptException, o);
447 static int processStatusBool(int status)
449 PyObject* o = processStatus(status);
459 static PyObject* processStatusReturnInt(int status, int returnValue)
461 PyObject* o = processStatus(status);
467 o = Py_BuildValue("i", returnValue);
472 static PyObject* processStatusReturnCryptHandle(int status, int returnValue)
475 PyObject* o = processStatus(status);
482 o2 = Py_BuildValue("(i)", returnValue);
483 o = PyObject_CallObject(cryptHandleClass, o2);
489 static PyObject* processStatusReturnCryptQueryInfo(int status, CRYPT_QUERY_INFO returnValue)
492 PyObject* o = processStatus(status);
499 o2 = Py_BuildValue("(siiii)", returnValue.algoName, returnValue.blockSize, returnValue.minKeySize, returnValue.keySize, returnValue.maxKeySize);
500 o = PyObject_CallObject(cryptQueryInfoClass, o2);
506 static PyObject* processStatusReturnCryptObjectInfo(int status, CRYPT_OBJECT_INFO returnValue)
509 PyObject* o = processStatus(status);
516 o2 = Py_BuildValue("(iiiis#)", returnValue.objectType, returnValue.cryptAlgo, returnValue.cryptMode, returnValue.hashAlgo, returnValue.salt, returnValue.saltSize);
517 o = PyObject_CallObject(cryptObjectInfoClass, o2);
523 pyBeforeModuleFunctions =
"""
525 static PyMethodDef module_functions[] =
528 pyBeforeInts =
r""" {0, 0}
531 DL_EXPORT(void) initcryptlib_py(void)
534 PyObject* moduleDict;
537 PyObject *globalsDict;
539 module = Py_InitModule("cryptlib_py", module_functions);
540 moduleDict = PyModule_GetDict(module);
542 CryptException = PyErr_NewException("cryptlib_py.CryptException", NULL, NULL);
543 PyDict_SetItemString(moduleDict, "CryptException", CryptException);
545 globalsDict = PyEval_GetGlobals();
547 "from array import *\n\
549 class CryptHandle:\n\
550 def __init__(self, value):\n\
551 self.__dict__['value'] = value\n\
552 def __int__(self):\n\
554 def __str__(self):\n\
555 return str(self.value)\n\
556 def __repr__(self):\n\
557 return str(self.value)\n\
558 def __getattr__(self, name):\n\
559 name = name.upper()\n\
560 if not name.startswith('CRYPT_'):\n\
561 name = 'CRYPT_' + name\n\
562 nameVal = globals()[name]\n\
564 return cryptGetAttribute(self, nameVal)\n\
565 except CryptException, ex:\n\
566 length = cryptGetAttributeString(self, nameVal, None)\n\
567 buf = array('c', '0' * length)\n\
568 length = cryptGetAttributeString(self, nameVal, buf)\n\
569 return ''.join(buf[:length])\n\
570 def __setattr__(self, name, value):\n\
571 name = name.upper()\n\
572 if not name.startswith('CRYPT_'):\n\
573 name = 'CRYPT_' + name\n\
574 nameVal = globals()[name]\n\
575 if isinstance(value, types.IntType) or isinstance(value, CryptHandle):\n\
576 cryptSetAttribute(self, nameVal, value)\n\
578 cryptSetAttributeString(self, nameVal, value)\n",
579 Py_file_input, globalsDict, moduleDict);
583 "class CRYPT_QUERY_INFO:\n\
584 def __init__(self, algoName, blockSize, minKeySize, keySize, maxKeySize):\n\
585 self.algoName = algoName\n\
586 self.blockSize = blockSize\n\
587 self.minKeySize = minKeySize\n\
588 self.keySize = keySize\n\
589 self.maxKeySize = maxKeySize\n",
590 Py_file_input, globalsDict, moduleDict);
593 "class CRYPT_OBJECT_INFO:\n\
594 def __init__(self, objectType, cryptAlgo, cryptMode, hashAlgo, salt):\n\
595 self.objectType = objectType\n\
596 self.cryptAlgo = cryptAlgo\n\
597 self.cryptMode = cryptMode\n\
598 self.hashAlgo = hashAlgo\n\
600 Py_file_input, globalsDict, moduleDict);
602 cryptHandleClass = PyMapping_GetItemString(moduleDict, "CryptHandle");
603 cryptQueryInfoClass = PyMapping_GetItemString(moduleDict, "CRYPT_QUERY_INFO");
604 cryptObjectInfoClass = PyMapping_GetItemString(moduleDict, "CRYPT_OBJECT_INFO");
606 Py_DECREF(globalsDict);
611 paramCharPtrTemplate =
"%(name)s, # string\n"
612 paramIntTemplate =
"%(name)s, # integer\n"
613 paramIntTypeTemplate =
"%(name)s, # %(type)s\n"
614 paramEnumTypeTemplate =
"%(name)s, # %(type)s\n"
616 classPrefix =
"class crypt:\n"
618 outFile = os.path.join(outDir,
"cryptlib.py")
622 setupPy =
r"""#!/usr/bin/env python
624 from distutils.core import setup, Extension
627 if sys.platform == "win32":
628 ext = Extension("cryptlib_py",
629 sources=["python.c"],
630 library_dirs=['../binaries'],
633 ext = Extension("cryptlib_py",
634 sources=["python.c"],
638 setup(name="cryptlib_py", ext_modules=[ext])
641 elif language ==
"net":
642 typedefEnumTemplate =
"// %(typedefName)s"
643 typedefEnumElementTemplate =
"public const int %(name)-NPADs = %(value)-VPADs;"
645 typedefEnumElementTemplateComment = typedefEnumElementTemplate +
" // %(comment)s"
646 simpleEnumElementTemplate =
"public const int %(name)-NPADs = %(value)-VPADs;"
647 simpleEnumElementTemplateComment = simpleEnumElementTemplate +
" // %(comment)s"
650 defineTemplate = simpleEnumElementTemplate
651 defineTemplateComment = simpleEnumElementTemplateComment
652 exceptionPrefix =
"""
653 [StructLayout(LayoutKind.Sequential, Pack=0, CharSet=CharSet.Ansi)]
654 public class CRYPT_QUERY_INFO
656 [MarshalAs(UnmanagedType.ByValTStr, SizeConst=64)]public String algoName;
657 public int blockSize;
658 public int minKeySize;
660 public int maxKeySize;
662 public CRYPT_QUERY_INFO(){}
664 public CRYPT_QUERY_INFO(String newAlgoName, int newBlockSize, int newMinKeySize, int newKeySize, int newMaxKeySize)
666 algoName = newAlgoName;
667 blockSize = newBlockSize;
668 minKeySize = newMinKeySize;
669 keySize = newKeySize;
670 maxKeySize = newMaxKeySize;
674 [StructLayout(LayoutKind.Sequential, Pack=0, CharSet=CharSet.Ansi)]
675 public class CRYPT_OBJECT_INFO
677 public int objectType;
678 public int cryptAlgo;
679 public int cryptMode;
681 [MarshalAs(UnmanagedType.ByValArray, SizeConst=32)]public byte[] salt;
684 public CRYPT_OBJECT_INFO()
690 public CRYPT_OBJECT_INFO(int newObjectType, int newCryptAlgo, int newCryptMode, int newHashAlgo, byte[] newSalt)
692 objectType = newObjectType;
693 cryptAlgo = newCryptAlgo;
694 cryptMode = newCryptMode;
695 hashAlgo = newHashAlgo;
699 public class CryptException : ApplicationException
701 public int Status { get { return (int)Data["Status"]; } }
703 public int ExtraInfo { get { return (int)Data["ExtraInfo"]; } }
705 public CryptException(int status)
706 : base(convertMessage(status))
708 Data.Add("Status", status);
711 public CryptException(int status, int extra)
712 : base(convertMessage(status))
714 Data.Add("Status", status);
715 Data.Add("ExtraInfo", extra);
718 private static string convertMessage(int status)
720 String prefix = Convert.ToString(status) + ": ";
724 exceptionPostfix =
"""\
725 default: return prefix + "Unknown Exception ?!?!";
729 exceptionTemplate =
"""\
730 case crypt.%(name)s: return prefix + "%(comment)s";
732 addFunctionWrappers = 1
733 wholeFunctionDeclaration =
None
734 functionDeclaration =
"public static "
735 returnIntDeclaration =
"int "
736 returnVoidDeclaration =
"void "
739 paramWhiteSpace =
"\t\t\t\t\t\t"
740 paramVoidPtrTemplate =
"byte[] %(name)s,\n"
741 addFunctionAlternate = 0
742 paramCharPtrTemplate =
"String %(name)s,\n"
743 paramIntTemplate =
"int %(name)s,\n"
744 paramIntTypeTemplate =
"int %(name)s, // %(type)s\n"
745 wrapperLengthTemplate =
"%(1)s == null ? 0 : %(1)s.Length, "
746 wrapperStringLengthTemplate =
"%(1)s == null ? 0 : new UTF8Encoding().GetByteCount(%(1)s), "
747 wrapperStringReplace = (
"byte[]",
"String")
748 wrapperStringTemplate =
"%(1)s == null ? null : new UTF8Encoding().GetBytes(%(1)s)"
752 paramEnumTypeTemplate =
"int %(name)s, // %(type)s\n"
754 classPrefix =
"""using System;
755 using System.Runtime.InteropServices;
765 /* Helper Functions */
767 private static void processStatus(int status)
769 if (status < crypt.OK)
770 throw new CryptException(status);
774 private static void processStatus(int status, int extraInfo)
776 if (status < crypt.OK)
777 throw new CryptException(status, extraInfo);
780 private static void checkIndices(byte[] array, int sequenceOffset, int sequenceLength)
784 if (sequenceOffset == 0)
787 throw new IndexOutOfRangeException();
790 int arrayLength = array.Length;
792 if (sequenceOffset < 0 ||
793 sequenceOffset >= arrayLength ||
794 sequenceOffset + sequenceLength > arrayLength)
795 throw new IndexOutOfRangeException();
798 private static void getPointer(byte[] buffer, int bufferOffset, ref GCHandle bufferHandle, ref IntPtr bufferPtr)
802 bufferHandle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
803 bufferPtr = Marshal.UnsafeAddrOfPinnedArrayElement(buffer, bufferOffset);
806 private static void releasePointer(GCHandle bufferHandle)
808 if (bufferHandle.IsAllocated)
818 s = open(inFile).read()
828 rawTypes = [
"char",
"int",
"void"]
830 rawParamStructsDict = {}
831 newParamStructsDict = {}
832 newReturnStructsDict = {}
833 newDiscardedStructsDict = {}
834 lengthIndicesDict = {}
835 offsetIndicesDict= {}
838 print "Parsing input file and generating %s files..." % language
842 s = re.search(
r"#ifndef _CRYPTLIB_DEFINED\n(.*)\n#endif", s, re.DOTALL).group(1)
846 s = s[re.search(
r"#define C_INOUT.*?\n", s, re.DOTALL).end() : ]
851 endifMatch = re.search(
r"#endif.*?\n", s, re.DOTALL)
852 if endifMatch ==
None:
854 ifdefIndex = s.rfind(
"#if", 0, endifMatch.start())
855 s = s[ : ifdefIndex] + s[endifMatch.end() : ]
861 functionParamterPattern = re.compile(
r"((C_CHECK_RETVAL|C_NONNULL_ARG\s*\(\s*\([ \t0-9,]+\s*\)\s*\))\s+(\\\n)?)", re.DOTALL)
863 deleteExtended = functionParamterPattern.search(s)
864 if deleteExtended ==
None:
866 s = s[ : deleteExtended.start(1) ] + s[ deleteExtended.end(1) : ]
871 typedefEnumPattern = re.compile(
r"typedef[ \t]+enum[ \t]+{([^}]*)}\s*(\w*);", re.DOTALL)
874 typedefEnumMatch = typedefEnumPattern.search(s)
875 while typedefEnumMatch:
878 enumContents, typedefName = typedefEnumMatch.groups()
879 enumTypes.append(typedefName)
885 namePad = str(
max( [len(e[0])
for e
in enumTuples] ) )
886 valuePad = str(
max( [len(e[1])
for e
in enumTuples] ) )
889 newTypedefEnum = typedefEnumTemplate % vars()
890 for enumTuple
in enumTuples:
891 name, value, comment = enumTuple
893 paddedTemplate = typedefEnumElementTemplate.replace(
"NPAD", namePad).replace(
"VPAD", valuePad)
894 newEnum = paddedTemplate % vars()
896 paddedTemplate = typedefEnumElementTemplateComment.replace(
"NPAD", namePad).replace(
"VPAD", valuePad)
897 newEnum = paddedTemplate % vars()
899 newTypedefEnum +=
"\n"
900 newTypedefEnum += newEnum
906 sInts += newTypedefEnum +
"\n"
909 s = s[ : typedefEnumMatch.start()] + newTypedefEnum + s[typedefEnumMatch.end() : ]
912 typedefEnumMatch = typedefEnumPattern.search(s, typedefEnumMatch.start() + len(newTypedefEnum))
921 simpleEnumPattern = re.compile(
r"enum[ \t]+{([^}]*)};", re.DOTALL)
924 simpleEnumMatch = simpleEnumPattern.search(s)
925 while simpleEnumMatch:
928 enumContents = simpleEnumMatch.group(1)
934 namePad = str(
max( [len(e[0])
for e
in enumTuples] ) )
935 valuePad = str(
max( [len(e[1])
for e
in enumTuples] ) )
939 for enumTuple
in enumTuples:
940 name, value, comment = enumTuple
942 paddedTemplate = simpleEnumElementTemplate.replace(
"NPAD", namePad).replace(
"VPAD", valuePad)
943 newEnum = paddedTemplate % vars()
945 paddedTemplate = simpleEnumElementTemplateComment.replace(
"NPAD", namePad).replace(
"VPAD", valuePad)
946 newEnum = paddedTemplate % vars()
948 newSimpleEnum +=
"\n"
949 newSimpleEnum += newEnum
955 sInts += newSimpleEnum +
"\n"
958 s = s[ : simpleEnumMatch.start()] + newSimpleEnum + s[simpleEnumMatch.end() : ]
961 simpleEnumMatch = simpleEnumPattern.search(s, simpleEnumMatch.start() + len(newSimpleEnum))
966 definePattern = re.compile(
r"#define[ \t]+(\w+)[ \t]+([-\w]+)[ \t]*(/\*.*\*/*)?")
968 exceptionString = exceptionPrefix
971 defineMatch = definePattern.search(s)
975 name, value, comment = defineMatch.groups()
976 if not name.startswith(
"CRYPT_"):
977 raise "name doesn't start with CRYPT_"+name
978 name = name.replace(
"CRYPT_",
"")
982 paddedTemplate = defineTemplate.replace(
"NPAD", defineNPad).replace(
"VPAD", defineVPad)
983 newDefine = paddedTemplate % vars()
985 comment = comment[2:-2].strip()
986 paddedTemplate = defineTemplateComment.replace(
"NPAD", defineNPad).replace(
"VPAD", defineVPad)
987 newDefine = paddedTemplate % vars()
993 sInts += newDefine +
"\n"
996 s = s[ : defineMatch.start()] + newDefine + s[defineMatch.end() : ]
999 if name.startswith(
"ERROR_")
or name.startswith(
"ENVELOPE_RESOURCE"):
1000 exceptionString += exceptionTemplate % vars()
1003 defineMatch = definePattern.search(s, defineMatch.start() + len(newDefine))
1005 exceptionString += exceptionPostfix
1009 definePattern = re.compile(
r"#define[ \t]+(\w+)[ \t]+\([ \t]*([-0-9]+)[ \)]*\)[ \t]*(/\*.*\*/*)?")
1011 exceptionString = exceptionPrefix
1014 defineMatch = definePattern.search(s)
1018 name, value, comment = defineMatch.groups()
1019 if not name.startswith(
"CRYPT_"):
1020 raise "name doesn't start with CRYPT_"+name
1021 name = name.replace(
"CRYPT_",
"")
1025 paddedTemplate = defineTemplate.replace(
"NPAD", defineNPad).replace(
"VPAD", defineVPad)
1026 newDefine = paddedTemplate % vars()
1028 comment = comment[2:-2].strip()
1029 paddedTemplate = defineTemplateComment.replace(
"NPAD", defineNPad).replace(
"VPAD", defineVPad)
1030 newDefine = paddedTemplate % vars()
1036 sInts += newDefine +
"\n"
1039 s = s[ : defineMatch.start()] + newDefine + s[defineMatch.end() : ]
1042 if name.startswith(
"ERROR_")
or name.startswith(
"ENVELOPE_RESOURCE"):
1043 exceptionString += exceptionTemplate % vars()
1046 defineMatch = definePattern.search(s, defineMatch.start() + len(newDefine))
1048 exceptionString += exceptionPostfix
1052 definePattern = re.compile(
r"#define[ \t]+[^(]+\([^\)]*\)([^\n]*\\\n)*[^\n]*")
1053 defineMatch = definePattern.search(s)
1057 define = defineMatch.group()
1058 newDefine = commentPrefix +
"CRYPTLIBCONVERTER - NOT SUPPORTED:\n" + define
1059 newDefine = newDefine.replace(
"\n",
"\n"+commentPrefix)
1060 s = s[ : defineMatch.start()] + newDefine + s[defineMatch.end() : ]
1061 defineMatch = definePattern.search(s, defineMatch.start() + len(newDefine))
1065 typedefIntPattern = re.compile(
r"typedef[ \t]+int[ \t]+([^ \t]*)[ \t]*;[ \t]*\n")
1066 typedefIntMatch = typedefIntPattern.search(s)
1067 while typedefIntMatch:
1068 typedefInt = typedefIntMatch.group()
1069 typedefIntName = typedefIntMatch.group(1)
1070 intTypes.append(typedefIntName)
1073 newTypedefInt = commentPrefix +
"CRYPTLIBCONVERTER - NOT NEEDED: " + typedefInt
1074 s = s[ : typedefIntMatch.start()] + newTypedefInt + s[typedefIntMatch.end() : ]
1075 typedefIntMatch = typedefIntPattern.search(s, typedefIntMatch.start() + len(newTypedefInt))
1080 typedefStructPattern = re.compile(
r"typedef[ \t]+struct[ \t]\{[^}]*}[ \t]*([^;]+);")
1081 typedefStructMatch = typedefStructPattern.search(s)
1082 while typedefStructMatch:
1083 typedefStruct = typedefStructMatch.group()
1084 typedefStructName = typedefStructMatch.group(1)
1085 structTypes.append(typedefStructName)
1088 newTypedefStruct = commentPrefix +
"CRYPTLIBCONVERTER - NOT SUPPORTED:\n" + typedefStruct
1089 newTypedefStruct = newTypedefStruct.replace(
"\n",
"\n"+commentPrefix)
1090 s = s[ : typedefStructMatch.start()] + newTypedefStruct + s[typedefStructMatch.end() : ]
1091 typedefStructMatch = typedefStructPattern.search(s, typedefStructMatch.start() + len(newTypedefStruct))
1097 functionPattern = re.compile(
r"C_RET[ \t]+([^ \t]+)[ \t]*\(([^\)]*)\);", re.DOTALL)
1098 functionMatch = functionPattern.search(s)
1099 while functionMatch:
1100 function = functionMatch.group()
1101 functionName, functionParams = functionMatch.groups()
1102 if not functionName.startswith(
"crypt"):
1103 raise "name doesn't start with crypt"+functionName
1104 functionName = functionName[len(
"crypt") : ]
1105 functionNames.append(functionName)
1114 rawParamStructsDict[functionName] = paramStructs
1135 discardIntIndex = -1
1137 returnVoidPtrIndex = -1
1138 discardInLengthIndex1 = -1
1139 discardInLengthIndex2 = -1
1144 for p
in paramStructs[1:]:
1145 p2 = paramStructs[index-1]
1146 if p.isPtr
and p.type==
"void" and p2.type==
"CRYPT_KEYID_TYPE":
1154 for p
in paramStructs:
1155 if p.isOut
and p.isPtr
and (p.category==
"intType" or p.type==
"int" or p.category==
"structType"):
1156 if returnIntIndex != -1:
1157 if discardIntIndex != -1:
1158 raise "Found two returned ints to discard?!"
1159 discardIntIndex = returnIntIndex
1160 returnIntIndex = index
1164 if returnIntIndex != -1:
1165 newReturnStructsDict[functionName] = paramStructs[returnIntIndex]
1168 if discardIntIndex != -1:
1169 newDiscardedStructsDict[functionName] = paramStructs[discardIntIndex]
1172 newParamStructs = [paramStructs[count]
1173 for count
in range(len(paramStructs))
1174 if count
not in (discardIntIndex, returnIntIndex)]
1183 if index >= len(newParamStructs):
1185 p = newParamStructs[index]
1186 if p.isPtr
and p.type==
"void":
1191 newp.category =
"rawType"
1192 newp.name = p.name+
"Offset"
1193 newParamStructs = newParamStructs[:index+1] + [newp] + newParamStructs[index+1:]
1194 offsetIndices.append(index+1)
1195 if not p.isOut
and len(newParamStructs)> index+2
and newParamStructs[index+2].type ==
"int":
1196 lengthIndices.append(index+2)
1201 newParamStructsDict[functionName] = newParamStructs
1202 lengthIndicesDict[functionName] = lengthIndices
1203 offsetIndicesDict[functionName] = offsetIndices
1206 if wholeFunctionDeclaration:
1207 newFunction = wholeFunctionDeclaration % functionName
1209 sFuncs += newFunction +
"\n"
1211 sModFuncs += (moduleFunctionEntry % (functionName, functionName)) +
"\n"
1215 newFunction = functionDeclaration
1216 if returnIntIndex != -1:
1217 if newReturnStructsDict.get(functionName).category ==
"structType":
1218 newFunction += newReturnStructsDict.get(functionName).type +
" "
1220 newFunction += returnIntDeclaration
1222 newFunction += returnVoidDeclaration
1223 newFunction += functionName + paramsPrefix
1224 if len(newParamStructs):
1225 newFunction +=
"\n" + paramWhiteSpace
1226 if offsetIndices
or lengthIndices:
1227 newFunctionWrapper = newFunction
1228 newFunctionWrapperArgs =
""
1230 newFunctionWrapper =
None
1237 if offsetIndices
and lengthIndices
and functionName
not in (
"Encrypt",
"Decrypt"):
1238 newFunctionStringWrapper = newFunction
1239 newFunctionStringWrapperArgs =
""
1241 newFunctionStringWrapper =
None
1242 newFunctionStringWrapperArgs =
""
1244 for p
in newParamStructs:
1245 if p.category ==
"rawType" and p.type ==
"void" and p.isPtr:
1246 template = paramVoidPtrTemplate
1247 previousBufferName = p.name
1248 elif p.category ==
"rawType" and p.type ==
"char" and p.isPtr:
1249 template = paramCharPtrTemplate
1250 elif p.category ==
"rawType" and p.type ==
"int" and not p.isPtr:
1251 template = paramIntTemplate
1252 elif p.category ==
"intType" and not p.isPtr:
1253 template = paramIntTypeTemplate
1254 elif p.category ==
"enumType" and not p.isPtr:
1255 template = paramEnumTypeTemplate
1258 raise "Unrecognized parameter type! " + str(p)
1261 if index == len(newParamStructs)-1:
1262 template = template[:].replace(
",",
"")
1265 newFunction += template % vars(p)
1266 newFunction += paramWhiteSpace
1270 if addFunctionWrappers
and newFunctionWrapper
and \
1271 index
not in offsetIndices
and index
not in lengthIndices:
1273 anyMoreParams = [e
for e
in range(index+1, len(newParamStructs))
1274 if e
not in offsetIndices
and e
not in lengthIndices]
1277 if not anyMoreParams:
1278 template = template[:].replace(
",",
"")
1279 newFunctionWrapper += template % vars(p)
1280 newFunctionWrapper += paramWhiteSpace
1283 newFunctionWrapperArgs += p.name
1284 newFunctionWrapperArgs +=
", "
1287 if newFunctionStringWrapper:
1288 newFunctionStringWrapper += template % vars(p)
1289 newFunctionStringWrapper += paramWhiteSpace
1290 if p.type==
"void" and p.isPtr
and not p.isOut:
1291 newFunctionStringWrapperArgs += wrapperStringTemplate % {
"1":p.name};
1293 newFunctionStringWrapperArgs += p.name
1294 newFunctionStringWrapperArgs +=
", "
1297 if index
in offsetIndices:
1298 newFunctionWrapperArgs +=
"0, "
1299 newFunctionStringWrapperArgs +=
"0, "
1300 elif index
in lengthIndices:
1301 newFunctionWrapperArgs += wrapperLengthTemplate % {
"1":previousBufferName}
1302 newFunctionStringWrapperArgs += wrapperStringLengthTemplate % {
"1":previousBufferName}
1306 newFunction += paramsPostfix
1307 if newFunctionWrapper:
1308 newFunctionWrapper += paramsPostfix
1309 if newFunctionStringWrapper:
1310 newFunctionStringWrapper += paramsPostfix
1314 if addFunctionAlternate:
1315 if newFunction.find(paramVoidPtrAlternate[0]) != -1:
1316 newFunction +=
"\n" + newFunction.replace(*paramVoidPtrAlternate)
1319 if addFunctionWrappers
and newFunctionWrapper:
1320 newFunctionWrapper = newFunctionWrapper.replace(
"native ",
"")
1321 newFunctionWrapper = newFunctionWrapper[:-1] +
" { return %s(%s); }" % (functionName, newFunctionWrapperArgs[:-2])
1322 if returnIntIndex == -1:
1323 newFunctionWrapper = newFunctionWrapper.replace(
"return ",
"")
1325 if addFunctionAlternate:
1326 newFunctionWrapper2 = newFunctionWrapper.replace(*paramVoidPtrAlternate)
1327 newFunctionWrapper2 = newFunctionWrapper2.replace(
"capacity()",
"length")
1328 newFunctionWrapper +=
"\n" + newFunctionWrapper2
1329 newFunction +=
"\n" + newFunctionWrapper
1330 if addFunctionWrappers
and newFunctionStringWrapper:
1331 newFunctionStringWrapper = newFunctionStringWrapper.replace(
"native ",
"")
1332 newFunctionStringWrapper = newFunctionStringWrapper[:-1] +
" { return %s(%s); }" % (functionName, newFunctionStringWrapperArgs[:-2])
1333 newFunctionStringWrapper = newFunctionStringWrapper.replace(*wrapperStringReplace)
1334 if returnIntIndex == -1:
1335 newFunctionStringWrapper = newFunctionStringWrapper.replace(
"return ",
"")
1336 newFunction +=
"\n" + newFunctionStringWrapper
1339 if functionName ==
"GetAttributeString" and language ==
"java":
1341 public static String GetAttributeString(
1342 int cryptHandle, // CRYPT_HANDLE
1343 int attributeType // CRYPT_ATTRIBUTE_TYPE
1344 ) throws CryptException
1346 int length = GetAttributeString(cryptHandle, attributeType, (byte[])null);
1347 byte[] bytes = new byte[length];
1348 length = GetAttributeString(cryptHandle, attributeType, bytes);
1349 return new String(bytes, 0, length);
1352 elif functionName ==
"GetAttributeString" and language ==
"net":
1354 public static String GetAttributeString(
1355 int cryptHandle, // CRYPT_HANDLE
1356 int attributeType // CRYPT_ATTRIBUTE_TYPE
1359 int length = GetAttributeString(cryptHandle, attributeType, null);
1360 byte[] bytes = new byte[length];
1361 length = GetAttributeString(cryptHandle, attributeType, bytes);
1362 return new UTF8Encoding().GetString(bytes, 0, length);
1367 elif functionName ==
"AddRandom":
1368 if language ==
"java":
1370 public static native void AddRandom(
1372 ) throws CryptException;
1374 elif language ==
"net":
1376 public static void AddRandom(
1383 if s[functionMatch.end()+1] !=
"\n":
1386 s = s[ : functionMatch.start()] + newFunction + s[functionMatch.end() : ]
1387 functionMatch = functionPattern.search(s, functionMatch.start() + len(newFunction))
1391 if language !=
"java" and language !=
"net":
1393 match = re.search(
r"/\*(.*?)\*/", s, re.DOTALL)
1398 commentStrings = (commentPrefix + match.group(1) +
" ").split(
"\n")
1399 newComment = commentStrings[0]
1400 for commentString
in commentStrings[1:]:
1401 if commentString.startswith(
"\t"):
1402 newComment +=
"\n" + commentPrefix + (
" " * (inFileTabSize-2)) + commentString[1:]
1403 elif commentString.startswith(
" "):
1404 newComment +=
"\n" + commentPrefix + commentString[1:]
1406 newComment +=
"\n" + commentPrefix + commentString
1409 idx = commentString.find(
"\n")
1410 s = s[ : match.start()] + newComment + s[match.end() : ]
1414 s = s.replace(
"\n",
"\n\t")
1421 if language==
"java":
1425 s = classPrefix + s + classPostfix
1428 if not os.path.exists(
"cryptlib"):
1429 os.mkdir(
"./cryptlib")
1430 os.chdir(
"./cryptlib")
1432 print "Writing java files..."
1433 f = open(
"crypt.java",
"w")
1436 f = open(
"CryptException.java",
"w")
1437 f.write(exceptionString)
1439 f = open(
"CRYPT_QUERY_INFO.java",
"w")
1440 f.write(cryptQueryInfoString)
1442 f = open(
"CRYPT_OBJECT_INFO.java",
"w")
1443 f.write(cryptObjectInfoString)
1447 print "Compiling java files..."
1448 print os.popen4(
"javac -classpath .. crypt.java")[1].read()
1449 print os.popen4(
"javac -classpath .. CryptException.java")[1].read()
1450 print os.popen4(
"javac -classpath .. CRYPT_QUERY_INFO.java")[1].read()
1451 print os.popen4(
"javac -classpath .. CRYPT_OBJECT_INFO.java")[1].read()
1455 print "Generating jar file..."
1456 print os.popen4(
"jar cf cryptlib.jar cryptlib/crypt.class cryptlib/CryptException.class cryptlib/CRYPT_QUERY_INFO.class cryptlib/CRYPT_OBJECT_INFO.class cryptlib")[1].read()
1458 print "Generating JNI header file..."
1459 print os.popen4(
"javah -classpath . -o cryptlib_jni.h -jni cryptlib.crypt")[1].read()
1461 s = open(
"cryptlib_jni.h").read()
1462 os.remove(
"cryptlib_jni.h")
1464 print "Generating JNI source file..."
1473 startIndex = s.find(
"#undef")
1474 endIndex = s.find(
"/*\n * Class", startIndex)
1476 s = s[startIndex : endIndex]
1478 startIndex = endIndex
1479 endIndex = sold.find(
"#ifdef", startIndex)
1480 s2 = sold[startIndex : endIndex]
1485 #include "../crypt.h"
1490 #include <stdio.h> //printf
1491 #include <stdlib.h> //malloc, free
1495 /* Helper Functions */
1497 int processStatus(JNIEnv *env, jint status)
1500 jmethodID exConstructor;
1503 if (status >= cryptlib_crypt_OK)
1506 exClass = (*env)->FindClass(env, "cryptlib/CryptException");
1509 printf("java_jni.c:processStatus - no class?!\n");
1513 exConstructor = (*env)->GetMethodID(env, exClass, "<init>", "(I)V");
1514 if (exConstructor == 0)
1516 printf("java_jni.c:processStatus - no constructor?!\n");
1520 obj = (*env)->NewObject(env, exClass, exConstructor, status);
1523 printf("java_jni.c:processStatus - no object?!\n");
1527 if ((*env)->Throw(env, obj) < 0)
1529 printf("java_jni.c:processStatus - failed to throw?!\n");
1535 jobject processStatusReturnCryptQueryInfo(JNIEnv *env, int status, CRYPT_QUERY_INFO returnValue)
1538 jmethodID exConstructor;
1542 if (status < cryptlib_crypt_OK)
1545 exClass = (*env)->FindClass(env, "cryptlib/CRYPT_QUERY_INFO");
1548 printf("java_jni.c:processStatusReturnCryptQueryInfo - no class?!\n");
1552 exConstructor = (*env)->GetMethodID(env, exClass, "<init>", "(Ljava/lang/String;IIII)V");
1553 if (exConstructor == 0)
1555 printf("java_jni.c:processStatusReturnCryptQueryInfo - no constructor?!\n");
1559 algoName = (*env)->NewStringUTF(env, returnValue.algoName);
1561 obj = (*env)->NewObject(env, exClass, exConstructor, algoName, returnValue.blockSize, returnValue.minKeySize, returnValue.keySize, returnValue.maxKeySize);
1564 printf("java_jni.c:processStatusReturnCryptQueryInfo - no object?!\n");
1571 jobject processStatusReturnCryptObjectInfo(JNIEnv *env, int status, CRYPT_OBJECT_INFO returnValue)
1574 jmethodID exConstructor;
1578 if (status < cryptlib_crypt_OK)
1581 exClass = (*env)->FindClass(env, "cryptlib/CRYPT_OBJECT_INFO");
1584 printf("java_jni.c:processStatusReturnCryptObjectInfo - no class?!\n");
1588 exConstructor = (*env)->GetMethodID(env, exClass, "<init>", "(IIII[B)V");
1589 if (exConstructor == 0)
1591 printf("java_jni.c:processStatusReturnCryptObjectInfo - no constructor?!\n");
1595 salt = (*env)->NewByteArray(env, returnValue.saltSize);
1596 (*env)->SetByteArrayRegion(env, salt, 0, returnValue.saltSize, returnValue.salt);
1598 obj = (*env)->NewObject(env, exClass, exConstructor, returnValue.objectType, returnValue.cryptAlgo, returnValue.cryptMode, returnValue.hashAlgo, salt);
1601 printf("java_jni.c:processStatusReturnCryptObjectInfo - no object?!\n");
1608 int checkIndicesArray(JNIEnv *env, jbyteArray array, int sequenceOffset, int sequenceLength)
1615 if (sequenceOffset == 0)
1619 exClass = (*env)->FindClass(env, "java/lang/ArrayIndexOutOfBoundsException");
1621 printf("java_jni.c:checkIndicesArray - no class?!\n");
1623 if ((*env)->ThrowNew(env, exClass, "") < 0)
1624 printf("java_jni.c:checkIndicesArray - failed to throw?!\n");
1629 arrayLength = (*env)->GetArrayLength(env, array);
1631 if (sequenceOffset < 0 ||
1632 sequenceOffset >= arrayLength ||
1633 sequenceOffset + sequenceLength > arrayLength)
1635 exClass = (*env)->FindClass(env, "java/lang/ArrayIndexOutOfBoundsException");
1637 printf("java_jni.c:checkIndicesArray - no class?!\n");
1639 if ((*env)->ThrowNew(env, exClass, "") < 0)
1640 printf("java_jni.c:checkIndicesArray - failed to throw?!\n");
1646 int getPointerArray(JNIEnv* env, jbyteArray array, jbyte** bytesPtrPtr)
1652 (*bytesPtrPtr) = NULL;
1656 (*bytesPtrPtr) = (*env)->GetByteArrayElements(env, array, &isCopy);
1658 if (*bytesPtrPtr == NULL)
1660 printf("java_jni.c:getPointer - failed to get elements of array?!\n");
1666 void releasePointerArray(JNIEnv* env,jbyteArray array, jbyte* bytesPtr)
1668 if (bytesPtr == NULL)
1670 (*env)->ReleaseByteArrayElements(env, array, bytesPtr, 0);
1673 int checkIndicesNIO(JNIEnv *env, jobject byteBuffer, int sequenceOffset, int sequenceLength)
1675 jlong byteBufferLength;
1678 if (byteBuffer == NULL)
1680 if (sequenceOffset == 0)
1684 exClass = (*env)->FindClass(env, "java/lang/ArrayIndexOutOfBoundsException");
1686 printf("java_jni.c:checkIndicesNIO - no class?!\n");
1688 if ((*env)->ThrowNew(env, exClass, "") < 0)
1689 printf("java_jni.c:checkIndicesNIO - failed to throw?!\n");
1694 byteBufferLength = (*env)->GetDirectBufferCapacity(env, byteBuffer);
1695 if (byteBufferLength == -1)
1697 exClass = (*env)->FindClass(env, "java/lang/UnsupportedOperationException");
1699 printf("java_jni.c:checkIndicesNIO - no class?!\n");
1701 if ((*env)->ThrowNew(env, exClass,
1702 "Either a non-direct ByteBuffer was passed or your JVM doesn't support JNI access to direct ByteBuffers") < 0)
1703 printf("java_jni.c:checkIndicesNIO - failed to throw?!\n");
1707 if (sequenceOffset < 0 ||
1708 sequenceOffset >= byteBufferLength ||
1709 sequenceOffset + sequenceLength > byteBufferLength)
1711 exClass = (*env)->FindClass(env, "java/lang/ArrayIndexOutOfBoundsException");
1713 printf("java_jni.c:checkIndicesNIO - no class?!\n");
1715 if ((*env)->ThrowNew(env, exClass, "") < 0)
1716 printf("java_jni.c:checkIndicesNIO - failed to throw?!\n");
1722 int getPointerNIO(JNIEnv* env, jobject byteBuffer, jbyte** bytesPtrPtr)
1726 if (byteBuffer == NULL)
1728 (*bytesPtrPtr) = NULL;
1732 (*bytesPtrPtr) = (*env)->GetDirectBufferAddress(env, byteBuffer);
1734 if (*bytesPtrPtr == NULL)
1736 exClass = (*env)->FindClass(env, "java/lang/UnsupportedOperationException");
1738 printf("java_jni.c:getPointerNIO - no class?!\n");
1740 if ((*env)->ThrowNew(env, exClass, "Your JVM doesn't support JNI access to direct ByteBuffers") < 0)
1741 printf("java_jni.c:getPointerNIO - failed to throw?!\n");
1747 void releasePointerNIO(JNIEnv* env,jbyteArray array, jbyte* bytesPtr)
1751 int getPointerString(JNIEnv* env, jstring str, jbyte** bytesPtrPtr)
1755 const jbyte* rawBytesPtr;
1764 (*bytesPtrPtr) = NULL;
1768 rawBytesPtr = (*env)->GetStringUTFChars(env, str, &isCopy);
1770 if (rawBytesPtr == NULL)
1772 printf("java_jni.c:getPointerString - failed to get elements of String?!\n");
1776 strLength = (*env)->GetStringUTFLength(env, str);
1779 (*bytesPtrPtr) = (jbyte*)malloc(strLength*2+2); // this is unicode, therefore \0 is two bytes long
1781 (*bytesPtrPtr) = (jbyte*)malloc(strLength+1);
1784 if (*bytesPtrPtr == NULL)
1786 exClass = (*env)->FindClass(env, "java/lang/OutOfMemoryError");
1788 printf("java_jni.c:getPointerString - no class?!\n");
1790 if ((*env)->ThrowNew(env, exClass, "") < 0)
1791 printf("java_jni.c:getPointerString - failed to throw?!\n");
1792 (*env)->ReleaseStringUTFChars(env, str, rawBytesPtr);
1797 status = asciiToUnicode (*bytesPtrPtr, strLength*2+2, rawBytesPtr, strLength+1);
1798 if (status == CRYPT_ERROR_BADDATA) {
1799 (*env)->ReleaseStringUTFChars(env, str, rawBytesPtr);
1803 memcpy(*bytesPtrPtr, rawBytesPtr, strLength);
1804 (*bytesPtrPtr)[strLength] = 0;
1807 (*env)->ReleaseStringUTFChars(env, str, rawBytesPtr);
1812 void releasePointerString(JNIEnv* env, jstring str, jbyte* bytesPtr)
1814 if (bytesPtr == NULL)
1821 #endif /* USE_JAVA */
1824 functionPattern = re.compile(
r"JNIEXPORT ([^ \t]+) JNICALL Java_cryptlib_crypt_([^ \t\n]+)\n[ \t]*\(([^\)]*)\);")
1825 functionMatch = functionPattern.search(s)
1826 while functionMatch:
1830 function = functionMatch.group()
1831 functionReturnType, functionName, functionPrototype = functionMatch.groups()
1834 if functionName ==
"AddRandom__I":
1839 p.category =
"intType"
1846 p2.category =
"intType"
1847 p2.name =
"pollType"
1849 rawParamStructs = [p,p2]
1850 newParamStructs = [p2,p2]
1852 functionName = functionName.split(
"__")[0]
1858 if functionName.find(
"__") != -1:
1859 if functionName.find(
"ByteBuffer") != -1:
1863 functionName = functionName.split(
"__")[0]
1866 rawParamStructs = rawParamStructsDict[functionName]
1867 newParamStructs = newParamStructsDict[functionName]
1868 if newReturnStructsDict.get(functionName):
1869 returnName = newReturnStructsDict.get(functionName).name
1870 returnType = newReturnStructsDict.get(functionName).type
1871 returnCategory = newReturnStructsDict.get(functionName).category
1875 if newDiscardedStructsDict.get(functionName):
1876 discardName = newDiscardedStructsDict.get(functionName).name
1884 startIndex = functionMatch.start(3) - functionMatch.start()
1885 endIndex = functionMatch.end(3) - functionMatch.start()
1886 function = function[ : startIndex] + newFunctionParams + function[ endIndex : ]
1888 newFunctionBody =
"\nint status = 0;\n"
1891 for p
in rawParamStructs:
1892 if p.name == returnName
or p.name == discardName:
1894 if p.isPtr
and p.type==
"void":
1895 arguments +=
"%sPtr + %sOffset, " % (p.name, p.name)
1896 elif p.isPtr
and p.type==
"char":
1897 arguments +=
"%sPtr, " % p.name
1899 arguments += p.name +
", "
1900 arguments = arguments[:-2]
1903 if returnCategory ==
"intType" or returnType==
"int":
1904 newFunctionBody +=
"jint %s = 0;\n" % returnName
1906 newFunctionBody += returnType +
" %s;\n" % returnName
1908 newFunctionBody +=
"jint %s = 0;\n" % discardName
1911 arrayNames = [p.name
for p
in newParamStructs
if p.isPtr]
1912 charArrayNames = [p.name
for p
in newParamStructs
if p.isPtr
and p.type==
"char"]
1913 voidArrayNames = [p.name
for p
in newParamStructs
if p.isPtr
and p.type==
"void"]
1914 outVoidArrayNames = [p.name
for p
in newParamStructs
if p.isPtr
and p.type==
"void" and p.isOut]
1917 for n
in arrayNames:
1918 newFunctionBody +=
"jbyte* " + n +
"Ptr = 0;\n"
1919 newFunctionBody +=
"\n"
1923 for n
in charArrayNames:
1924 newFunctionBody +=
"if (!getPointerString(env, %(n)s, &%(n)sPtr))\n\tgoto finish;\n" % vars()
1925 newFunctionBody +=
"\n"
1929 if outVoidArrayNames
and functionName.find(
"PopData") == -1:
1930 for n
in outVoidArrayNames:
1931 argumentsWithNull = arguments.replace(
"%sPtr + %sOffset" % (n,n),
"NULL")
1932 newFunctionBody +=
"if (!processStatus(env, crypt%s(%s)))\n\tgoto finish;\n" % (functionName, argumentsWithNull)
1933 newFunctionBody +=
"\n"
1934 elif functionName.find(
"PopData") != -1:
1935 newFunctionBody +=
"//CryptPopData is a special case that doesn't have the length querying call\n\n"
1937 for n
in voidArrayNames:
1938 index = [p.name
for p
in newParamStructs].
index(n)
1939 if n
in outVoidArrayNames:
1940 lengthName = returnName
1942 if len(newParamStructs)<=index+2
or newParamStructs[index+2].category !=
"rawType" or newParamStructs[index+2].type !=
"int":
1945 lengthName = newParamStructs[index+2].name
1946 newFunctionBody +=
"if (!checkIndices%(voidTag)s(env, %(n)s, %(n)sOffset, %(lengthName)s))\n\tgoto finish;\n" % vars()
1947 newFunctionBody +=
"\n"
1948 for n
in voidArrayNames:
1949 newFunctionBody +=
"if (!getPointer%(voidTag)s(env, %(n)s, &%(n)sPtr))\n\tgoto finish;\n" % vars()
1951 if newFunctionBody[-2] !=
"\n":
1952 newFunctionBody +=
"\n"
1953 newFunctionBody +=
"status = crypt%s(%s);\n\n" % (functionName, arguments)
1956 newFunctionBody +=
"finish:\n"
1958 for n
in voidArrayNames:
1959 newFunctionBody +=
"releasePointer%(voidTag)s(env, %(n)s, %(n)sPtr);\n" % vars()
1960 for n
in charArrayNames:
1961 newFunctionBody +=
"releasePointerString(env, %(n)s, %(n)sPtr);\n" % vars()
1968 if returnCategory ==
"intType" or returnType ==
"int":
1969 newFunctionBody +=
"processStatus(env, status);\n"
1970 newFunctionBody +=
"return(%s);\n" % returnName
1971 elif returnType ==
"CRYPT_QUERY_INFO":
1972 newFunctionBody +=
"return(processStatusReturnCryptQueryInfo(env, status, %s));\n" % returnName
1973 elif returnType ==
"CRYPT_OBJECT_INFO":
1974 newFunctionBody +=
"return(processStatusReturnCryptObjectInfo(env, status, %s));\n" % returnName
1976 newFunctionBody +=
"processStatus(env, status);\n"
1978 newFunctionBody = newFunctionBody[:-1]
1979 newFunctionBody = newFunctionBody.replace(
"\n",
"\n\t");
1980 newFunction = function[:-1]+
"\n{" + newFunctionBody +
"\n}"
1983 s = s[ : functionMatch.start()] + newFunction + s[functionMatch.end() : ]
1986 functionMatch = functionPattern.search(s, functionMatch.start() + len(newFunction))
1988 f = open(
"java_jni.c",
"w")
1994 elif language ==
"python":
2002 moduleFunctions =
""
2003 s = pyBeforeExceptions + exceptionString + pyBeforeFuncs + sFuncs + \
2004 pyBeforeModuleFunctions + moduleFunctions + sModFuncs + \
2005 pyBeforeInts + sInts + \
2010 functionPattern = re.compile(
r"static PyObject\* python_crypt([^\(]+)[^{]+{([^}]*)}", re.DOTALL)
2011 functionMatch = functionPattern.search(s)
2012 while functionMatch:
2021 functionName, functionBody = functionMatch.groups()
2024 rawParamStructs = rawParamStructsDict[functionName]
2025 newParamStructs = newParamStructsDict[functionName]
2026 lengthIndices = lengthIndicesDict[functionName]
2027 offsetIndices = offsetIndicesDict[functionName]
2030 if newReturnStructsDict.get(functionName):
2031 returnName = newReturnStructsDict.get(functionName).name
2032 returnType = newReturnStructsDict.get(functionName).type
2033 returnCategory = newReturnStructsDict.get(functionName).category
2036 if newDiscardedStructsDict.get(functionName):
2037 discardName = newDiscardedStructsDict.get(functionName).name
2041 newFunctionBody =
"\nint status = 0;\n"
2045 for p
in rawParamStructs:
2046 if p.name == returnName
or p.name == discardName:
2048 if p.isPtr
and p.type==
"void":
2049 arguments +=
"%sPtr, " % (p.name)
2050 elif p.isPtr
and p.type==
"char":
2051 arguments +=
"%sPtr, " % p.name
2053 arguments += p.name +
", "
2054 arguments = arguments[:-2]
2057 if returnCategory ==
"intType" or returnType==
"int":
2058 newFunctionBody +=
"int %s = 0;\n" % returnName
2060 newFunctionBody += returnType +
" %s;\n" % returnName
2062 newFunctionBody +=
"int %s = 0;\n" % discardName
2065 for p
in newParamStructs:
2066 if index
not in offsetIndices:
2068 newFunctionBody +=
"PyObject* %s = NULL;\n" % p.name
2070 newFunctionBody +=
"int %s = 0;\n" % p.name
2074 arrayNames = [p.name
for p
in newParamStructs
if p.isPtr]
2075 charArrayNames = [p.name
for p
in newParamStructs
if p.isPtr
and p.type==
"char"]
2076 voidArrayNames = [p.name
for p
in newParamStructs
if p.isPtr
and p.type==
"void"]
2077 outVoidArrayNames = [p.name
for p
in newParamStructs
if p.isPtr
and p.type==
"void" and p.isOut]
2080 for n
in arrayNames:
2081 newFunctionBody +=
"unsigned char* " + n +
"Ptr = 0;\n"
2082 newFunctionBody +=
"\n"
2089 parseFormatString =
""
2092 for p
in newParamStructs:
2093 if index
not in lengthIndices
and index
not in offsetIndices:
2094 if p.isPtr
and p.type==
"char":
2095 parseFormatString +=
"O"
2096 parseArgsList.append(
"&" + p.name)
2097 elif p.isPtr
and p.type==
"void":
2098 parseFormatString +=
"O"
2099 parseArgsList.append(
"&" + p.name)
2101 parseFormatString +=
"i"
2102 parseArgsList.append(
"&" + p.name)
2106 if newFunctionBody[-2] !=
"\n":
2107 newFunctionBody +=
"\n"
2110 if functionName ==
"AddRandom":
2111 newFunctionBody +=
"""\
2112 //Special case to handle SLOWPOLL / FASTPOLL values
2113 if (PyArg_ParseTuple(args, "i", &randomDataLength))
2114 return processStatus(cryptAddRandom(NULL, randomDataLength));\n\n"""
2116 newFunctionBody +=
"""\
2117 if (!PyArg_ParseTuple(args, "%s", %s))
2118 return(NULL);\n\n""" % (parseFormatString,
", ".join(parseArgsList))
2124 for n
in charArrayNames:
2125 newFunctionBody +=
"if (!getPointerReadString(%(n)s, &%(n)sPtr))\n\tgoto finish;\n" % vars()
2126 newFunctionBody +=
"\n"
2130 if outVoidArrayNames
and functionName.find(
"PopData") == -1:
2131 for n
in outVoidArrayNames:
2132 argumentsWithNull = arguments.replace(
"%sPtr" % (n),
"NULL")
2133 newFunctionBody +=
"if (!processStatusBool(crypt%s(%s)))\n\tgoto finish;\n" % (functionName, argumentsWithNull)
2134 newFunctionBody +=
"\n"
2135 elif functionName.find(
"PopData") != -1:
2136 newFunctionBody +=
"//CryptPopData is a special case that doesn't have the length querying call\n\n"
2140 for n
in voidArrayNames:
2141 index = [p.name
for p
in newParamStructs].
index(n)
2143 if n
in outVoidArrayNames:
2144 lengthName = returnName
2146 if len(newParamStructs)<=index+2
or newParamStructs[index+2].category !=
"rawType" or newParamStructs[index+2].type !=
"int":
2149 lengthName = newParamStructs[index+2].name
2150 if n
in outVoidArrayNames
and functionName.find(
"PopData") == -1:
2151 newFunctionBody +=
"if (!getPointerWriteCheckIndices%(voidTag)s(%(n)s, &%(n)sPtr, &%(lengthName)s))\n\tgoto finish;\n" % vars()
2153 if lengthName ==
"1":
2154 newFunctionBody +=
"if (!getPointerReadNoLength%(voidTag)s(%(n)s, &%(n)sPtr))\n\tgoto finish;\n" % vars()
2159 if n
not in outVoidArrayNames
and functionName
not in (
"Encrypt",
"Decrypt"):
2160 newFunctionBody +=
"if (!getPointerRead(%(n)s, &%(n)sPtr, &%(lengthName)s))\n\tgoto finish;\n" % vars()
2162 newFunctionBody +=
"if (!getPointerWrite(%(n)s, &%(n)sPtr, &%(lengthName)s))\n\tgoto finish;\n" % vars()
2164 if newFunctionBody[-2] !=
"\n":
2165 newFunctionBody +=
"\n"
2166 newFunctionBody +=
"status = crypt%s(%s);\n\n" % (functionName, arguments)
2169 newFunctionBody +=
"finish:\n"
2171 for n
in voidArrayNames:
2172 newFunctionBody +=
"releasePointer(%(n)s, %(n)sPtr);\n" % vars()
2173 for n
in charArrayNames:
2174 newFunctionBody +=
"releasePointerString(%(n)s, %(n)sPtr);\n" % vars()
2177 if returnCategory ==
"intType":
2178 newFunctionBody +=
"return(processStatusReturnCryptHandle(status, %s));" % returnName
2179 elif returnType ==
"CRYPT_QUERY_INFO":
2180 newFunctionBody +=
"return(processStatusReturnCryptQueryInfo(status, %s));" % returnName
2181 elif returnType ==
"CRYPT_OBJECT_INFO":
2182 newFunctionBody +=
"return(processStatusReturnCryptObjectInfo(status, %s));" % returnName
2183 elif returnType ==
"int":
2184 newFunctionBody +=
"return(processStatusReturnInt(status, %s));" % returnName
2186 newFunctionBody +=
"return(processStatus(status));"
2188 newFunctionBody = newFunctionBody.replace(
"\n",
"\n\t")
2191 s = s[ : functionMatch.start(2)] + newFunctionBody +
"\n" + s[functionMatch.end(2) : ]
2194 functionMatch = functionPattern.search(s, functionMatch.start() + len(newFunction))
2196 f = open(
"python.c",
"w")
2201 f = open(
"setup.py",
"w")
2205 elif language ==
"net":
2206 flagForAddRandomHack = 0
2209 functionPattern = re.compile(
r"public static ([^ \t]+) ([^ \t\n]+)\([ \t\n]*([^\)]*)\);")
2210 functionMatch = functionPattern.search(s)
2211 while functionMatch:
2215 function = functionMatch.group()
2216 functionReturnType, functionName, functionPrototype = functionMatch.groups()
2219 if functionName ==
"AddRandom":
2220 flagForAddRandomHack += 1
2221 if flagForAddRandomHack == 2:
2226 p.category =
"intType"
2227 p.name =
"IntPtr.Zero"
2233 p2.category =
"intType"
2234 p2.name =
"pollType"
2236 rawParamStructs = [p,p2]
2237 newParamStructs = [p2,p2]
2239 functionName = functionName.split(
"__")[0]
2242 flagForAddRandomHack =
None
2245 rawParamStructs = rawParamStructsDict[functionName]
2246 newParamStructs = newParamStructsDict[functionName]
2247 if newReturnStructsDict.get(functionName):
2248 returnName = newReturnStructsDict.get(functionName).name
2249 returnType = newReturnStructsDict.get(functionName).type
2250 returnCategory = newReturnStructsDict.get(functionName).category
2253 if newDiscardedStructsDict.get(functionName):
2254 discardName = newDiscardedStructsDict.get(functionName).name
2261 newFunctionParams = functionPrototype
2262 startIndex = functionMatch.start(3) - functionMatch.start()
2263 endIndex = functionMatch.end(3) - functionMatch.start()
2264 function = function[ : startIndex] + newFunctionParams + function[ endIndex : ]
2266 newFunctionBody =
"\n"
2269 for p
in rawParamStructs:
2270 if p.name == returnName
or p.name == discardName:
2271 arguments +=
"%sPtr, " % p.name
2272 elif p.isPtr
and p.type==
"void":
2273 arguments +=
"%sPtr, " % p.name
2274 elif p.isPtr
and p.type==
"char":
2275 arguments +=
"%sPtr, " % p.name
2277 arguments += p.name +
", "
2278 arguments = arguments[:-2]
2281 if returnCategory ==
"structType":
2282 newFunctionBody +=
"IntPtr %sPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(%s)));\n" % (returnName, returnType)
2283 newFunctionBody +=
"%s %s = new %s();\n" % (returnType, returnName, returnType)
2285 newFunctionBody +=
"IntPtr %sPtr = Marshal.AllocHGlobal(4);\n" % returnName
2287 newFunctionBody +=
"IntPtr %sPtr = Marshal.AllocHGlobal(4);\n" % discardName
2290 arrayNames = [p.name
for p
in newParamStructs
if p.isPtr]
2291 charArrayNames = [p.name
for p
in newParamStructs
if p.isPtr
and p.type==
"char"]
2292 voidArrayNames = [p.name
for p
in newParamStructs
if p.isPtr
and p.type==
"void"]
2293 outVoidArrayNames = [p.name
for p
in newParamStructs
if p.isPtr
and p.type==
"void" and p.isOut]
2296 for n
in arrayNames:
2298 newFunctionBody +=
"GCHandle %sHandle = new GCHandle();\nIntPtr %sPtr = IntPtr.Zero;\n" % (n,n)
2299 if n
in charArrayNames:
2300 newFunctionBody +=
"byte[] %sArray = new UTF8Encoding().GetBytes(%s);\n" % (n,n)
2302 newFunctionBody +=
"try\n{\n"
2307 for n
in charArrayNames:
2308 newFunctionBody +=
"getPointer(%(n)sArray, 0, ref %(n)sHandle, ref %(n)sPtr);\n" % vars()
2312 if outVoidArrayNames
and functionName.find(
"PopData") == -1:
2313 for n
in outVoidArrayNames:
2314 argumentsWithNull = arguments.replace(
"%sPtr + %sOffset" % (n,n),
"NULL")
2315 newFunctionBody +=
"processStatus(wrapped_%s(%s));\n" % (functionName, argumentsWithNull)
2316 newFunctionBody +=
"int %s = Marshal.ReadInt32(%sPtr);\n" % (returnName, returnName)
2317 elif functionName.find(
"PopData") != -1
or functionName.find(
"PushData") != -1:
2318 newFunctionBody +=
"int %s = 0;\n" % returnName
2319 newFunctionBody +=
"int status;\n"
2321 for n
in voidArrayNames:
2322 index = [p.name
for p
in newParamStructs].
index(n)
2323 if n
in outVoidArrayNames:
2324 lengthName = returnName
2326 if len(newParamStructs)<=index+2
or newParamStructs[index+2].category !=
"rawType" or newParamStructs[index+2].type !=
"int":
2329 lengthName = newParamStructs[index+2].name
2330 newFunctionBody +=
"checkIndices(%(n)s, %(n)sOffset, %(lengthName)s);\n" % vars()
2331 for n
in voidArrayNames:
2332 newFunctionBody +=
"getPointer(%(n)s, %(n)sOffset, ref %(n)sHandle, ref %(n)sPtr);\n" % vars()
2334 newFunctionBody +=
"try\n{\n"
2336 if functionName.find(
"PopData") == -1
and functionName.find(
"PushData") == -1:
2337 newFunctionBody +=
"processStatus(wrapped_%s(%s));\n" % (functionName, arguments)
2339 newFunctionBody +=
"status = wrapped_%s(%s);\n" % (functionName, arguments)
2340 newFunctionBody +=
"%s = Marshal.ReadInt32(%sPtr);\n" % (returnName, returnName)
2341 newFunctionBody +=
"processStatus(status, %s);\n" %returnName
2346 if returnCategory ==
"structType":
2347 newFunctionBody +=
"Marshal.PtrToStructure(%sPtr, %s);\n" % (returnName, returnName)
2348 newFunctionBody +=
"return %s;\n" % returnName
2350 if functionName.find(
"PopData") == -1
and functionName.find(
"PushData") == -1:
2351 newFunctionBody +=
"return Marshal.ReadInt32(%sPtr);\n" % returnName
2353 newFunctionBody +=
"return %s;\n" %returnName
2355 if arrayNames
or returnName:
2356 newFunctionBody +=
"}\nfinally\n{\n"
2358 newFunctionBody +=
"Marshal.FreeHGlobal(%sPtr);\n" % returnName
2360 for n
in voidArrayNames:
2361 newFunctionBody +=
"releasePointer(%(n)sHandle);\n" % vars()
2362 for n
in charArrayNames:
2363 newFunctionBody +=
"releasePointer(%(n)sHandle);\n" % vars()
2364 newFunctionBody +=
"}\n"
2367 lines = newFunctionBody.split(
"\n")
2369 for count
in range(len(lines)):
2371 if line.startswith(
"}"):
2373 lines[count] = (
"\t" * brackets) + line
2374 if line.startswith(
"{"):
2376 newFunctionBody =
"\n".join(lines)
2378 newFunctionBody = newFunctionBody[:-1]
2379 newFunctionBody = newFunctionBody.replace(
"\n",
"\n\t");
2380 newFunction = function[:-1]+
"\n{" + newFunctionBody +
"\n}"
2381 newFunction = newFunction.replace(
"\n",
"\n\t");
2384 s = s[ : functionMatch.start()] + newFunction + s[functionMatch.end() : ]
2387 functionMatch = functionPattern.search(s, functionMatch.start() + len(newFunction))
2393 for functionName
in functionNames:
2394 rawParamStructs = rawParamStructsDict[functionName]
2396 for p
in rawParamStructs:
2398 parameters +=
"IntPtr %s, " % p.name
2400 parameters +=
"int %s, " % p.name
2401 parameters = parameters[:-2]
2403 s +=
'\t[DllImport("cl32.dll", EntryPoint="crypt%s")]\n\tprivate static extern int wrapped_%s(%s);\n\n' % (functionName, functionName, parameters)
2410 s += classPostfix + exceptionString +
"\n\n}"
2413 print "Writing .NET file..."
2414 f = open(
"cryptlib.cs",
"w")