├── .gitignore ├── Example ├── .gitignore ├── Example.pro └── main.cpp ├── LICENSE ├── NEncryptionKit.pro ├── NEncryptionKit ├── 3rdparty │ └── botan │ │ ├── botan.cpp │ │ ├── botan.h │ │ ├── botan.pri │ │ ├── configure.py │ │ ├── doc │ │ └── license.txt │ │ └── readme.txt ├── NEncryptionKit.pro ├── NEncryptionKit_inc.pri ├── NEncryptionKit_resource.rc ├── NEncryptionKit_src.pri ├── inc │ ├── nencryptionkit.h │ └── nencryptionkit_global.h └── src │ └── nencryptionkit.cpp ├── README.md ├── Scripts └── clear.bat └── _config.yml /.gitignore: -------------------------------------------------------------------------------- 1 | /NEncryptionKit.pro.user 2 | /NEncryptionKit/NEncryptionKit.pro.user 3 | /.qmake.stash 4 | -------------------------------------------------------------------------------- /Example/.gitignore: -------------------------------------------------------------------------------- 1 | # This file is used to ignore files which are generated 2 | # ---------------------------------------------------------------------------- 3 | 4 | *~ 5 | *.autosave 6 | *.a 7 | *.core 8 | *.moc 9 | *.o 10 | *.obj 11 | *.orig 12 | *.rej 13 | *.so 14 | *.so.* 15 | *_pch.h.cpp 16 | *_resource.rc 17 | *.qm 18 | .#* 19 | *.*# 20 | core 21 | !core/ 22 | tags 23 | .DS_Store 24 | .directory 25 | *.debug 26 | Makefile* 27 | *.prl 28 | *.app 29 | moc_*.cpp 30 | ui_*.h 31 | qrc_*.cpp 32 | Thumbs.db 33 | *.res 34 | *.rc 35 | /.qmake.cache 36 | /.qmake.stash 37 | 38 | # qtcreator generated files 39 | *.pro.user* 40 | 41 | # xemacs temporary files 42 | *.flc 43 | 44 | # Vim temporary files 45 | .*.swp 46 | 47 | # Visual Studio generated files 48 | *.ib_pdb_index 49 | *.idb 50 | *.ilk 51 | *.pdb 52 | *.sln 53 | *.suo 54 | *.vcproj 55 | *vcproj.*.*.user 56 | *.ncb 57 | *.sdf 58 | *.opensdf 59 | *.vcxproj 60 | *vcxproj.* 61 | 62 | # MinGW generated files 63 | *.Debug 64 | *.Release 65 | 66 | # Python byte code 67 | *.pyc 68 | 69 | # Binaries 70 | # -------- 71 | *.dll 72 | *.exe 73 | 74 | -------------------------------------------------------------------------------- /Example/Example.pro: -------------------------------------------------------------------------------- 1 | QT += core 2 | QT -= gui 3 | 4 | CONFIG += c++11 5 | 6 | TARGET = NEncryptionKit_Example 7 | CONFIG += console 8 | CONFIG -= app_bundle 9 | 10 | TEMPLATE = app 11 | 12 | SOURCES += main.cpp 13 | 14 | win32{ 15 | DESTDIR = $$PWD/../bin 16 | MOC_DIR = $$PWD/build_/moc 17 | RCC_DIR = $$PWD/build_/rcc 18 | OBJECTS_DIR = $$PWD/build_/obj 19 | } 20 | 21 | # import dll file 22 | include($$PWD/../NEncryptionKit/NEncryptionKit_inc.pri) 23 | -------------------------------------------------------------------------------- /Example/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "nencryptionkit.h" 5 | 6 | int main(int argc, char *argv[]) 7 | { 8 | QCoreApplication a(argc, argv); 9 | qDebug()<<"******************************************测试用例开始*****************************************************"; 10 | NEncryptionKit test_instance; 11 | qDebug()<<"----------------------------MD5测试开始----------------------------"; 12 | QString test_case_001("I am daodaoliang"); 13 | QString test_encry_str = test_instance.getMD5Hash(test_case_001); 14 | qDebug()<<"MD5前的字符串:" << test_case_001; 15 | qDebug()<<"MD5后的字符串:" << test_encry_str; 16 | qDebug()<<"----------------------------MD5测试结束----------------------------"; 17 | 18 | qDebug()<<"----------------------------SHA测试开始----------------------------"; 19 | QString test_case_002("I am nami"); 20 | QString test_encry_str_002 = test_instance.getSHAHash(test_case_002); 21 | qDebug()<<"SHA前的字符串:" << test_case_002; 22 | qDebug()<<"SHA后的字符串:" << test_encry_str_002; 23 | qDebug()<<"----------------------------SHA测试结束----------------------------"; 24 | 25 | qDebug()<<"----------------------------Kaiser测试开始-------------------------"; 26 | QString test_case_003("I am wangxiaowei"); 27 | qint8 test_case_key(7); 28 | QString test_encry_str_003 = test_case_003; 29 | bool ret = test_instance.getByKaiser(test_case_003, test_case_key); 30 | qDebug()<<"加密是否成功:"<', token) 501 | 502 | # Check for a grouping 503 | if match is not None: 504 | group = match.group(1) 505 | 506 | if group not in allowed_groups: 507 | raise LexerError('Unknown group "%s"' % (group), 508 | lexer.lineno) 509 | 510 | end_marker = '' 511 | 512 | token = lexer.get_token() 513 | while token != end_marker: 514 | to_obj.__dict__[py_var(group)].append(token) 515 | token = lexer.get_token() 516 | if token is None: 517 | raise LexerError('Group "%s" not terminated' % (group), 518 | lexer.lineno) 519 | 520 | elif token in name_val_pairs.keys(): 521 | next_val = lexer.get_token() 522 | 523 | if type(to_obj.__dict__[token]) is list: 524 | to_obj.__dict__[token].append(next_val) 525 | else: 526 | to_obj.__dict__[token] = next_val 527 | 528 | else: # No match -> error 529 | raise LexerError('Bad token "%s"' % (token), lexer.lineno) 530 | 531 | """ 532 | Convert a lex'ed map (from build-data files) from a list to a dict 533 | """ 534 | def force_to_dict(l): 535 | return dict(zip(l[::3],l[2::3])) 536 | 537 | """ 538 | Represents the information about a particular module 539 | """ 540 | class ModuleInfo(object): 541 | 542 | def __init__(self, infofile): 543 | 544 | lex_me_harder(infofile, self, 545 | ['source', 'header:internal', 'header:public', 546 | 'requires', 'os', 'arch', 'cc', 'libs', 547 | 'comment'], 548 | { 549 | 'load_on': 'auto', 550 | 'define': [], 551 | 'uses_tr1': 'false', 552 | 'need_isa': None, 553 | 'mp_bits': 0 }) 554 | 555 | def extract_files_matching(basedir, suffixes): 556 | for (dirpath, dirnames, filenames) in os.walk(basedir): 557 | if dirpath == basedir: 558 | for filename in filenames: 559 | if filename.startswith('.'): 560 | continue 561 | 562 | for suffix in suffixes: 563 | if filename.endswith(suffix): 564 | yield filename 565 | 566 | if self.source == []: 567 | self.source = list(extract_files_matching(self.lives_in, ['.cpp', '.S'])) 568 | 569 | if self.header_internal == [] and self.header_public == []: 570 | self.header_public = list(extract_files_matching(self.lives_in, ['.h'])) 571 | 572 | # Coerce to more useful types 573 | def convert_lib_list(l): 574 | result = {} 575 | for (targetlist, vallist) in zip(l[::3], l[2::3]): 576 | vals = vallist.split(',') 577 | for target in targetlist.split(','): 578 | result[target] = result.setdefault(target, []) + vals 579 | return result 580 | 581 | self.libs = convert_lib_list(self.libs) 582 | 583 | def add_dir_name(filename): 584 | if filename.count(':') == 0: 585 | return os.path.join(self.lives_in, filename) 586 | 587 | # modules can request to add files of the form 588 | # MODULE_NAME:FILE_NAME to add a file from another module 589 | # For these, assume other module is always in a 590 | # neighboring directory; this is true for all current uses 591 | return os.path.join(os.path.split(self.lives_in)[0], 592 | *filename.split(':')) 593 | 594 | self.source = [add_dir_name(s) for s in self.source] 595 | self.header_internal = [add_dir_name(s) for s in self.header_internal] 596 | self.header_public = [add_dir_name(s) for s in self.header_public] 597 | 598 | self.mp_bits = int(self.mp_bits) 599 | 600 | self.uses_tr1 = (True if self.uses_tr1 == 'yes' else False) 601 | 602 | if self.comment != []: 603 | self.comment = ' '.join(self.comment) 604 | else: 605 | self.comment = None 606 | 607 | def sources(self): 608 | return self.source 609 | 610 | def public_headers(self): 611 | return self.header_public 612 | 613 | def internal_headers(self): 614 | return self.header_internal 615 | 616 | def defines(self): 617 | return ['HAS_' + d for d in self.define] 618 | 619 | def compatible_cpu(self, archinfo, options): 620 | 621 | arch_name = archinfo.basename 622 | cpu_name = options.cpu 623 | 624 | if self.arch != []: 625 | if arch_name not in self.arch and cpu_name not in self.arch: 626 | return False 627 | 628 | if self.need_isa != None: 629 | if self.need_isa in options.disable_isa_extns: 630 | return False # explicitly disabled 631 | 632 | if self.need_isa in options.enable_isa_extns: 633 | return True # explicitly enabled 634 | 635 | # Default to whatever the CPU is supposed to support 636 | return self.need_isa in archinfo.isa_extensions_in(cpu_name) 637 | 638 | return True 639 | 640 | def compatible_os(self, os): 641 | return self.os == [] or os in self.os 642 | 643 | def compatible_compiler(self, cc): 644 | return self.cc == [] or cc in self.cc 645 | 646 | def tr1_ok(self, with_tr1): 647 | if self.uses_tr1: 648 | return with_tr1 in ['boost', 'system'] 649 | else: 650 | return True 651 | 652 | def dependencies(self): 653 | # utils is an implicit dep (contains types, etc) 654 | deps = self.requires + ['utils'] 655 | if self.parent_module != None: 656 | deps.append(self.parent_module) 657 | return deps 658 | 659 | """ 660 | Ensure that all dependencies of this module actually exist, warning 661 | about any that do not 662 | """ 663 | def dependencies_exist(self, modules): 664 | all_deps = [s.split('|') for s in self.dependencies()] 665 | 666 | for missing in [s for s in flatten(all_deps) if s not in modules]: 667 | logging.warn("Module '%s', dep of '%s', does not exist" % ( 668 | missing, self.basename)) 669 | 670 | def __cmp__(self, other): 671 | if self.basename < other.basename: 672 | return -1 673 | if self.basename == other.basename: 674 | return 0 675 | return 1 676 | 677 | class ArchInfo(object): 678 | def __init__(self, infofile): 679 | lex_me_harder(infofile, self, 680 | ['aliases', 'submodels', 'submodel_aliases', 'isa_extn'], 681 | { 'endian': None, 682 | 'family': None, 683 | 'unaligned': 'no' 684 | }) 685 | 686 | def convert_isa_list(input): 687 | isa_info = {} 688 | for line in self.isa_extn: 689 | (isa,cpus) = line.split(':') 690 | for cpu in cpus.split(','): 691 | isa_info.setdefault(cpu, []).append(isa) 692 | return isa_info 693 | 694 | self.isa_extn = convert_isa_list(self.isa_extn) 695 | 696 | self.submodel_aliases = force_to_dict(self.submodel_aliases) 697 | 698 | self.unaligned_ok = (1 if self.unaligned == 'ok' else 0) 699 | 700 | """ 701 | Return ISA extensions specific to this CPU 702 | """ 703 | def isa_extensions_in(self, cpu_type): 704 | return sorted(self.isa_extn.get(cpu_type, []) + 705 | self.isa_extn.get('all', [])) 706 | 707 | """ 708 | Return a list of all submodels for this arch, ordered longest 709 | to shortest 710 | """ 711 | def all_submodels(self): 712 | return sorted([(k,k) for k in self.submodels] + 713 | [k for k in self.submodel_aliases.items()], 714 | key = lambda k: len(k[0]), reverse = True) 715 | 716 | """ 717 | Return CPU-specific defines for build.h 718 | """ 719 | def defines(self, options): 720 | def form_macro(cpu_name): 721 | return cpu_name.upper().replace('.', '').replace('-', '_') 722 | 723 | macros = ['TARGET_ARCH_IS_%s' % 724 | (form_macro(self.basename.upper()))] 725 | 726 | if self.basename != options.cpu: 727 | macros.append('TARGET_CPU_IS_%s' % (form_macro(options.cpu))) 728 | 729 | enabled_isas = set(self.isa_extensions_in(options.cpu) + 730 | options.enable_isa_extns) 731 | disabled_isas = set(options.disable_isa_extns) 732 | 733 | isa_extensions = sorted(enabled_isas - disabled_isas) 734 | 735 | for isa in isa_extensions: 736 | macros.append('TARGET_CPU_HAS_%s' % (form_macro(isa))) 737 | 738 | endian = options.with_endian or self.endian 739 | 740 | if endian != None: 741 | macros.append('TARGET_CPU_IS_%s_ENDIAN' % (endian.upper())) 742 | logging.info('Assuming CPU is %s endian' % (endian)) 743 | 744 | unaligned_ok = options.unaligned_mem 745 | if unaligned_ok is None: 746 | unaligned_ok = self.unaligned_ok 747 | if unaligned_ok: 748 | logging.info('Assuming unaligned memory access works') 749 | 750 | if self.family is not None: 751 | macros.append('TARGET_CPU_IS_%s_FAMILY' % (self.family.upper())) 752 | 753 | macros.append('TARGET_UNALIGNED_MEMORY_ACCESS_OK %d' % (unaligned_ok)) 754 | 755 | return macros 756 | 757 | class CompilerInfo(object): 758 | def __init__(self, infofile): 759 | lex_me_harder(infofile, self, 760 | ['so_link_flags', 'mach_opt', 'mach_abi_linking'], 761 | { 'binary_name': None, 762 | 'macro_name': None, 763 | 'compile_option': '-c ', 764 | 'output_to_option': '-o ', 765 | 'add_include_dir_option': '-I', 766 | 'add_lib_dir_option': '-L', 767 | 'add_lib_option': '-l', 768 | 'lib_opt_flags': '', 769 | 'check_opt_flags': '', 770 | 'debug_flags': '', 771 | 'no_debug_flags': '', 772 | 'shared_flags': '', 773 | 'lang_flags': '', 774 | 'warning_flags': '', 775 | 'maintainer_warning_flags': '', 776 | 'visibility_build_flags': '', 777 | 'visibility_attribute': '', 778 | 'ar_command': None, 779 | 'makefile_style': '', 780 | 'has_tr1': False, 781 | }) 782 | 783 | self.so_link_flags = force_to_dict(self.so_link_flags) 784 | self.mach_abi_linking = force_to_dict(self.mach_abi_linking) 785 | 786 | self.mach_opt_flags = {} 787 | 788 | while self.mach_opt != []: 789 | proc = self.mach_opt.pop(0) 790 | if self.mach_opt.pop(0) != '->': 791 | raise Exception('Parsing err in %s mach_opt' % (self.basename)) 792 | 793 | flags = self.mach_opt.pop(0) 794 | regex = '' 795 | 796 | if len(self.mach_opt) > 0 and \ 797 | (len(self.mach_opt) == 1 or self.mach_opt[1] != '->'): 798 | regex = self.mach_opt.pop(0) 799 | 800 | self.mach_opt_flags[proc] = (flags,regex) 801 | 802 | del self.mach_opt 803 | 804 | """ 805 | Return the shared library build flags, if any 806 | """ 807 | def gen_shared_flags(self, options): 808 | def flag_builder(): 809 | if options.build_shared_lib: 810 | yield self.shared_flags 811 | if options.with_visibility: 812 | yield self.visibility_build_flags 813 | 814 | return ' '.join(list(flag_builder())) 815 | 816 | def gen_visibility_attribute(self, options): 817 | if options.build_shared_lib and options.with_visibility: 818 | return self.visibility_attribute 819 | return '' 820 | 821 | """ 822 | Return the machine specific ABI flags 823 | """ 824 | def mach_abi_link_flags(self, osname, arch, submodel, debug_p): 825 | 826 | def all(): 827 | if debug_p: 828 | return 'all-debug' 829 | return 'all' 830 | 831 | abi_link = set() 832 | for what in [all(), osname, arch, submodel]: 833 | if self.mach_abi_linking.get(what) != None: 834 | abi_link.add(self.mach_abi_linking.get(what)) 835 | 836 | if len(abi_link) == 0: 837 | return '' 838 | return ' ' + ' '.join(abi_link) 839 | 840 | """ 841 | Return the flags for MACH_OPT 842 | """ 843 | def mach_opts(self, arch, submodel): 844 | 845 | def submodel_fixup(tup): 846 | return tup[0].replace('SUBMODEL', submodel.replace(tup[1], '')) 847 | 848 | if submodel == arch: 849 | return '' 850 | 851 | if submodel in self.mach_opt_flags: 852 | return submodel_fixup(self.mach_opt_flags[submodel]) 853 | if arch in self.mach_opt_flags: 854 | return submodel_fixup(self.mach_opt_flags[arch]) 855 | 856 | return '' 857 | 858 | """ 859 | Return the flags for LIB_OPT 860 | """ 861 | def library_opt_flags(self, options): 862 | def gen_flags(): 863 | if options.debug_build: 864 | yield self.debug_flags 865 | 866 | if not options.no_optimizations: 867 | yield self.lib_opt_flags 868 | 869 | if not options.debug_build: 870 | yield self.no_debug_flags 871 | 872 | return (' '.join(gen_flags())).strip() 873 | 874 | """ 875 | Return the command needed to link a shared object 876 | """ 877 | def so_link_command_for(self, osname): 878 | if osname in self.so_link_flags: 879 | return self.so_link_flags[osname] 880 | if 'default' in self.so_link_flags: 881 | return self.so_link_flags['default'] 882 | return '' 883 | 884 | """ 885 | Return defines for build.h 886 | """ 887 | def defines(self, with_tr1): 888 | 889 | def tr1_macro(): 890 | if with_tr1: 891 | if with_tr1 == 'boost': 892 | return ['USE_BOOST_TR1'] 893 | elif with_tr1 == 'system': 894 | return ['USE_STD_TR1'] 895 | elif self.has_tr1: 896 | return ['USE_STD_TR1'] 897 | return [] 898 | 899 | return ['BUILD_COMPILER_IS_' + self.macro_name] + tr1_macro() 900 | 901 | class OsInfo(object): 902 | def __init__(self, infofile): 903 | lex_me_harder(infofile, self, 904 | ['aliases', 'target_features'], 905 | { 'os_type': None, 906 | 'obj_suffix': 'o', 907 | 'so_suffix': 'so', 908 | 'static_suffix': 'a', 909 | 'ar_command': 'ar crs', 910 | 'ar_needs_ranlib': False, 911 | 'install_root': '/usr/local', 912 | 'header_dir': 'include', 913 | 'lib_dir': 'lib', 914 | 'doc_dir': 'share/doc', 915 | 'build_shared': 'yes', 916 | 'install_cmd_data': 'install -m 644', 917 | 'install_cmd_exec': 'install -m 755' 918 | }) 919 | 920 | self.ar_needs_ranlib = bool(self.ar_needs_ranlib) 921 | 922 | self.build_shared = (True if self.build_shared == 'yes' else False) 923 | 924 | def ranlib_command(self): 925 | return ('ranlib' if self.ar_needs_ranlib else 'true') 926 | 927 | def defines(self): 928 | return ['TARGET_OS_IS_%s' % (self.basename.upper())] + \ 929 | ['TARGET_OS_HAS_' + feat.upper() 930 | for feat in sorted(self.target_features)] 931 | 932 | def fixup_proc_name(proc): 933 | proc = proc.lower().replace(' ', '') 934 | for junk in ['(tm)', '(r)']: 935 | proc = proc.replace(junk, '') 936 | return proc 937 | 938 | def canon_processor(archinfo, proc): 939 | proc = fixup_proc_name(proc) 940 | 941 | # First, try to search for an exact match 942 | for ainfo in archinfo.values(): 943 | if ainfo.basename == proc or proc in ainfo.aliases: 944 | return (ainfo.basename, ainfo.basename) 945 | 946 | for (match,submodel) in ainfo.all_submodels(): 947 | if proc == submodel or proc == match: 948 | return (ainfo.basename, submodel) 949 | 950 | logging.debug('Could not find an exact match for CPU "%s"' % (proc)) 951 | 952 | # Now, try searching via regex match 953 | for ainfo in archinfo.values(): 954 | for (match,submodel) in ainfo.all_submodels(): 955 | if re.search(match, proc) != None: 956 | logging.debug('Possible match "%s" with "%s" (%s)' % ( 957 | proc, match, submodel)) 958 | return (ainfo.basename, submodel) 959 | 960 | logging.debug('Known CPU names: ' + ' '.join( 961 | sorted(flatten([[ainfo.basename] + \ 962 | ainfo.aliases + \ 963 | [x for (x,_) in ainfo.all_submodels()] 964 | for ainfo in archinfo.values()])))) 965 | 966 | raise Exception('Unknown or unidentifiable processor "%s"' % (proc)) 967 | 968 | def guess_processor(archinfo): 969 | base_proc = platform.machine() 970 | 971 | if base_proc == '': 972 | raise Exception('Could not determine target CPU; set with --cpu') 973 | 974 | full_proc = fixup_proc_name(platform.processor()) or base_proc 975 | 976 | for ainfo in archinfo.values(): 977 | if ainfo.basename == base_proc or base_proc in ainfo.aliases: 978 | for (match,submodel) in ainfo.all_submodels(): 979 | if re.search(match, full_proc) != None: 980 | return (ainfo.basename, submodel) 981 | 982 | return canon_processor(archinfo, ainfo.basename) 983 | 984 | # No matches, so just use the base proc type 985 | return canon_processor(archinfo, base_proc) 986 | 987 | """ 988 | Read a whole file into memory as a string 989 | """ 990 | def slurp_file(filename): 991 | if filename is None: 992 | return '' 993 | return ''.join(open(filename).readlines()) 994 | 995 | """ 996 | Perform template substitution 997 | """ 998 | def process_template(template_file, variables): 999 | class PercentSignTemplate(string.Template): 1000 | delimiter = '%' 1001 | 1002 | try: 1003 | template = PercentSignTemplate(slurp_file(template_file)) 1004 | return template.substitute(variables) 1005 | except KeyError as e: 1006 | raise Exception('Unbound var %s in template %s' % (e, template_file)) 1007 | 1008 | """ 1009 | Create the template variables needed to process the makefile, build.h, etc 1010 | """ 1011 | def create_template_vars(build_config, options, modules, cc, arch, osinfo): 1012 | def make_cpp_macros(macros): 1013 | return '\n'.join(['#define BOTAN_' + macro for macro in macros]) 1014 | 1015 | """ 1016 | Figure out what external libraries are needed based on selected modules 1017 | """ 1018 | def link_to(): 1019 | libs = set() 1020 | for module in modules: 1021 | for (osname,link_to) in module.libs.items(): 1022 | if osname == 'all' or osname == osinfo.basename: 1023 | libs |= set(link_to) 1024 | else: 1025 | match = re.match('^all!(.*)', osname) 1026 | if match is not None: 1027 | exceptions = match.group(1).split(',') 1028 | if osinfo.basename not in exceptions: 1029 | libs |= set(link_to) 1030 | return sorted(libs) 1031 | 1032 | def objectfile_list(sources, obj_dir): 1033 | for src in sources: 1034 | (dir,file) = os.path.split(os.path.normpath(src)) 1035 | 1036 | if dir.startswith('src'): 1037 | parts = dir.split(os.sep)[1:] 1038 | if file == parts[-1] + '.cpp': 1039 | name = '_'.join(dir.split(os.sep)[1:]) + '.cpp' 1040 | else: 1041 | name = '_'.join(dir.split(os.sep)[1:]) + '_' + file 1042 | else: 1043 | name = file 1044 | 1045 | for src_suffix in ['.cpp', '.S']: 1046 | name = name.replace(src_suffix, '.' + osinfo.obj_suffix) 1047 | 1048 | yield os.path.join(obj_dir, name) 1049 | 1050 | 1051 | def choose_mp_bits(): 1052 | mp_bits = [mod.mp_bits for mod in modules if mod.mp_bits != 0] 1053 | 1054 | if mp_bits == []: 1055 | return 32 # default 1056 | 1057 | # Check that settings are consistent across modules 1058 | for mp_bit in mp_bits[1:]: 1059 | if mp_bit != mp_bits[0]: 1060 | raise Exception('Incompatible mp_bits settings found') 1061 | 1062 | return mp_bits[0] 1063 | 1064 | """ 1065 | Form snippets of makefile for building each source file 1066 | """ 1067 | def build_commands(sources, obj_dir, flags): 1068 | for (obj_file,src) in zip(objectfile_list(sources, obj_dir), sources): 1069 | yield '%s: %s\n\t$(CXX) %s%s $(%s_FLAGS) %s$? %s$@\n' % ( 1070 | obj_file, src, 1071 | cc.add_include_dir_option, 1072 | build_config.include_dir, 1073 | flags, 1074 | cc.compile_option, 1075 | cc.output_to_option) 1076 | 1077 | def makefile_list(items): 1078 | items = list(items) # force evaluation so we can slice it 1079 | return (' '*16).join([item + ' \\\n' for item in items[:-1]] + 1080 | [items[-1]]) 1081 | 1082 | def prefix_with_build_dir(path): 1083 | if options.with_build_dir != None: 1084 | return os.path.join(options.with_build_dir, path) 1085 | return path 1086 | 1087 | def warning_flags(normal_flags, 1088 | maintainer_flags, 1089 | maintainer_mode): 1090 | if maintainer_mode and maintainer_flags != '': 1091 | return maintainer_flags 1092 | return normal_flags 1093 | 1094 | return { 1095 | 'version_major': build_config.version_major, 1096 | 'version_minor': build_config.version_minor, 1097 | 'version_patch': build_config.version_patch, 1098 | 'version_vc_rev': build_config.version_vc_rev, 1099 | 'so_abi_rev': build_config.version_so_rev, 1100 | 'version': build_config.version_string, 1101 | 1102 | 'distribution_info': options.distribution_info, 1103 | 1104 | 'version_datestamp': build_config.version_datestamp, 1105 | 1106 | 'timestamp': build_config.timestamp(), 1107 | 'user': build_config.username(), 1108 | 'hostname': build_config.hostname(), 1109 | 'command_line': ' '.join(sys.argv), 1110 | 'local_config': slurp_file(options.local_config), 1111 | 'makefile_style': options.makefile_style or cc.makefile_style, 1112 | 1113 | 'makefile_path': prefix_with_build_dir('Makefile'), 1114 | 1115 | 'prefix': options.prefix or osinfo.install_root, 1116 | 'libdir': options.libdir or osinfo.lib_dir, 1117 | 'includedir': options.includedir or osinfo.header_dir, 1118 | 'docdir': options.docdir or osinfo.doc_dir, 1119 | 1120 | 'build_dir': build_config.build_dir, 1121 | 'doc_output_dir': build_config.doc_output_dir, 1122 | 1123 | 'build_doc_commands': build_config.build_doc_commands, 1124 | 1125 | 'python_dir': build_config.python_dir, 1126 | 1127 | 'os': options.os, 1128 | 'arch': options.arch, 1129 | 'submodel': options.cpu, 1130 | 1131 | 'mp_bits': choose_mp_bits(), 1132 | 1133 | 'cc': (options.compiler_binary or cc.binary_name) + 1134 | cc.mach_abi_link_flags(options.os, options.arch, 1135 | options.cpu, options.debug_build), 1136 | 1137 | 'lib_opt': cc.library_opt_flags(options), 1138 | 'mach_opt': cc.mach_opts(options.arch, options.cpu), 1139 | 'check_opt': '' if options.no_optimizations else cc.check_opt_flags, 1140 | 'lang_flags': cc.lang_flags + options.extra_flags, 1141 | 'warn_flags': warning_flags(cc.warning_flags, 1142 | cc.maintainer_warning_flags, 1143 | options.maintainer_mode), 1144 | 1145 | 'shared_flags': cc.gen_shared_flags(options), 1146 | 'visibility_attribute': cc.gen_visibility_attribute(options), 1147 | 1148 | 'so_link': cc.so_link_command_for(osinfo.basename), 1149 | 1150 | 'link_to': ' '.join([cc.add_lib_option + lib for lib in link_to()]), 1151 | 1152 | 'module_defines': make_cpp_macros(sorted(flatten([m.defines() for m in modules]))), 1153 | 1154 | 'target_os_defines': make_cpp_macros(osinfo.defines()), 1155 | 1156 | 'target_compiler_defines': make_cpp_macros( 1157 | cc.defines(options.with_tr1)), 1158 | 1159 | 'target_cpu_defines': make_cpp_macros(arch.defines(options)), 1160 | 1161 | 'include_files': makefile_list(build_config.public_headers), 1162 | 1163 | 'lib_objs': makefile_list( 1164 | objectfile_list(build_config.build_sources, 1165 | build_config.libobj_dir)), 1166 | 1167 | 'check_objs': makefile_list( 1168 | objectfile_list(build_config.check_sources, 1169 | build_config.checkobj_dir)), 1170 | 1171 | 'lib_build_cmds': '\n'.join( 1172 | build_commands(build_config.build_sources, 1173 | build_config.libobj_dir, 'LIB')), 1174 | 1175 | 'check_build_cmds': '\n'.join( 1176 | build_commands(build_config.check_sources, 1177 | build_config.checkobj_dir, 'CHECK')), 1178 | 1179 | 'python_obj_dir': build_config.pyobject_dir, 1180 | 1181 | 'python_objs': makefile_list( 1182 | objectfile_list(build_config.python_sources, 1183 | build_config.pyobject_dir)), 1184 | 1185 | 'python_build_cmds': '\n'.join( 1186 | build_commands(build_config.python_sources, 1187 | build_config.pyobject_dir, 'PYTHON')), 1188 | 1189 | 'ar_command': cc.ar_command or osinfo.ar_command, 1190 | 'ranlib_command': osinfo.ranlib_command(), 1191 | 'install_cmd_exec': osinfo.install_cmd_exec, 1192 | 'install_cmd_data': osinfo.install_cmd_data, 1193 | 1194 | 'check_prefix': prefix_with_build_dir(''), 1195 | 'lib_prefix': prefix_with_build_dir(''), 1196 | 1197 | 'static_suffix': osinfo.static_suffix, 1198 | 'so_suffix': osinfo.so_suffix, 1199 | 1200 | 'botan_config': prefix_with_build_dir( 1201 | os.path.join(build_config.build_dir, 1202 | build_config.config_shell_script())), 1203 | 1204 | 'botan_pkgconfig': prefix_with_build_dir( 1205 | os.path.join(build_config.build_dir, 1206 | build_config.pkg_config_file())), 1207 | 1208 | 'mod_list': '\n'.join(sorted([m.basename for m in modules])), 1209 | 1210 | 'python_version': options.python_version 1211 | } 1212 | 1213 | """ 1214 | Determine which modules to load based on options, target, etc 1215 | """ 1216 | def choose_modules_to_use(modules, archinfo, options): 1217 | 1218 | for mod in modules.values(): 1219 | mod.dependencies_exist(modules) 1220 | 1221 | to_load = [] 1222 | maybe_dep = [] 1223 | not_using_because = {} 1224 | 1225 | def cannot_use_because(mod, reason): 1226 | not_using_because.setdefault(reason, []).append(mod) 1227 | 1228 | for modname in options.enabled_modules: 1229 | if modname not in modules: 1230 | logging.warning("Unknown enabled module %s" % (modname)) 1231 | 1232 | for modname in options.disabled_modules: 1233 | if modname not in modules: 1234 | logging.warning("Unknown disabled module %s" % (modname)) 1235 | 1236 | for (modname, module) in modules.items(): 1237 | if modname in options.disabled_modules: 1238 | cannot_use_because(modname, 'disabled by user') 1239 | elif modname in options.enabled_modules: 1240 | to_load.append(modname) # trust the user 1241 | 1242 | elif not module.compatible_os(options.os): 1243 | cannot_use_because(modname, 'incompatible OS') 1244 | elif not module.compatible_compiler(options.compiler): 1245 | cannot_use_because(modname, 'incompatible compiler') 1246 | elif not module.compatible_cpu(archinfo, options): 1247 | cannot_use_because(modname, 'incompatible CPU') 1248 | elif not module.tr1_ok(options.with_tr1): 1249 | cannot_use_because(modname, 'missing TR1') 1250 | 1251 | else: 1252 | if module.load_on == 'never': 1253 | cannot_use_because(modname, 'disabled as buggy') 1254 | elif module.load_on == 'request': 1255 | cannot_use_because(modname, 'by request only') 1256 | elif module.load_on == 'dep': 1257 | maybe_dep.append(modname) 1258 | 1259 | elif module.load_on == 'always': 1260 | to_load.append(modname) 1261 | 1262 | elif module.load_on == 'asm_ok': 1263 | if options.asm_ok: 1264 | if options.no_autoload: 1265 | maybe_dep.append(modname) 1266 | else: 1267 | to_load.append(modname) 1268 | else: 1269 | cannot_use_because(modname, 1270 | 'uses assembly and --disable-asm set') 1271 | elif module.load_on == 'auto': 1272 | if options.no_autoload: 1273 | maybe_dep.append(modname) 1274 | else: 1275 | to_load.append(modname) 1276 | else: 1277 | logging.warning('Unknown load_on %s in %s' % ( 1278 | module.load_on, modname)) 1279 | 1280 | dependency_failure = True 1281 | 1282 | while dependency_failure: 1283 | dependency_failure = False 1284 | for modname in to_load: 1285 | for deplist in [s.split('|') for s in modules[modname].dependencies()]: 1286 | 1287 | dep_met = False 1288 | for mod in deplist: 1289 | if dep_met is True: 1290 | break 1291 | 1292 | if mod in to_load: 1293 | dep_met = True 1294 | elif mod in maybe_dep: 1295 | maybe_dep.remove(mod) 1296 | to_load.append(mod) 1297 | dep_met = True 1298 | 1299 | if dep_met == False: 1300 | dependency_failure = True 1301 | if modname in to_load: 1302 | to_load.remove(modname) 1303 | if modname in maybe_dep: 1304 | maybe_dep.remove(modname) 1305 | cannot_use_because(modname, 'dependency failure') 1306 | 1307 | for not_a_dep in maybe_dep: 1308 | cannot_use_because(not_a_dep, 'loaded only if needed by dependency') 1309 | 1310 | for reason in sorted(not_using_because.keys()): 1311 | disabled_mods = sorted(set([mod for mod in not_using_because[reason]])) 1312 | 1313 | if disabled_mods != []: 1314 | logging.info('Skipping, %s - %s' % ( 1315 | reason, ' '.join(disabled_mods))) 1316 | 1317 | for mod in sorted(to_load): 1318 | if mod.startswith('mp_'): 1319 | logging.info('Using MP module ' + mod) 1320 | if mod.startswith('simd_') and mod != 'simd_engine': 1321 | logging.info('Using SIMD module ' + mod) 1322 | if modules[mod].comment: 1323 | logging.info('%s: %s' % (mod, modules[mod].comment)) 1324 | 1325 | logging.debug('Loading modules %s', ' '.join(sorted(to_load))) 1326 | 1327 | return [modules[mod] for mod in to_load] 1328 | 1329 | """ 1330 | Load the info files about modules, targets, etc 1331 | """ 1332 | def load_info_files(options): 1333 | 1334 | def find_files_named(desired_name, in_path): 1335 | for (dirpath, dirnames, filenames) in os.walk(in_path): 1336 | if desired_name in filenames: 1337 | yield os.path.join(dirpath, desired_name) 1338 | 1339 | modules = dict([(mod.basename, mod) for mod in 1340 | [ModuleInfo(info) for info in 1341 | find_files_named('info.txt', options.src_dir)]]) 1342 | 1343 | def list_files_in_build_data(subdir): 1344 | for (dirpath, dirnames, filenames) in \ 1345 | os.walk(os.path.join(options.build_data, subdir)): 1346 | for filename in filenames: 1347 | if filename.endswith('.txt'): 1348 | yield os.path.join(dirpath, filename) 1349 | 1350 | def form_name(filepath): 1351 | return os.path.basename(filepath).replace('.txt', '') 1352 | 1353 | archinfo = dict([(form_name(info), ArchInfo(info)) 1354 | for info in list_files_in_build_data('arch')]) 1355 | 1356 | osinfo = dict([(form_name(info), OsInfo(info)) 1357 | for info in list_files_in_build_data('os')]) 1358 | 1359 | ccinfo = dict([(form_name(info), CompilerInfo(info)) 1360 | for info in list_files_in_build_data('cc')]) 1361 | 1362 | def info_file_load_report(type, num): 1363 | if num > 0: 1364 | logging.debug('Loaded %d %s info files' % (num, type)) 1365 | else: 1366 | logging.warning('Failed to load any %s info files' % (type)) 1367 | 1368 | info_file_load_report('CPU', len(archinfo)); 1369 | info_file_load_report('OS', len(osinfo)) 1370 | info_file_load_report('compiler', len(ccinfo)) 1371 | 1372 | return (modules, archinfo, ccinfo, osinfo) 1373 | 1374 | """ 1375 | Perform the filesystem operations needed to setup the build 1376 | """ 1377 | def setup_build(build_config, options, template_vars): 1378 | 1379 | """ 1380 | Choose the link method based on system availablity and user request 1381 | """ 1382 | def choose_link_method(req_method): 1383 | 1384 | def useable_methods(): 1385 | if 'symlink' in os.__dict__: 1386 | yield 'symlink' 1387 | if 'link' in os.__dict__: 1388 | yield 'hardlink' 1389 | yield 'copy' 1390 | 1391 | for method in useable_methods(): 1392 | if req_method is None or req_method == method: 1393 | return method 1394 | 1395 | logging.info('Could not use requested link method %s' % (req_method)) 1396 | return 'copy' 1397 | 1398 | """ 1399 | Copy or link the file, depending on what the platform offers 1400 | """ 1401 | def portable_symlink(filename, target_dir, method): 1402 | 1403 | if not os.access(filename, os.R_OK): 1404 | logging.warning('Missing file %s' % (filename)) 1405 | return 1406 | 1407 | if method == 'symlink': 1408 | def count_dirs(dir, accum = 0): 1409 | if dir in ['', '/', os.path.curdir]: 1410 | return accum 1411 | (dir,basename) = os.path.split(dir) 1412 | return accum + 1 + count_dirs(dir) 1413 | 1414 | dirs_up = count_dirs(target_dir) 1415 | 1416 | source = os.path.join(os.path.join(*[os.path.pardir]*dirs_up), 1417 | filename) 1418 | 1419 | target = os.path.join(target_dir, os.path.basename(filename)) 1420 | 1421 | os.symlink(source, target) 1422 | 1423 | elif method == 'hardlink': 1424 | os.link(filename, 1425 | os.path.join(target_dir, os.path.basename(filename))) 1426 | 1427 | elif method == 'copy': 1428 | shutil.copy(filename, target_dir) 1429 | 1430 | else: 1431 | raise Exception('Unknown link method %s' % (method)) 1432 | 1433 | def choose_makefile_template(style): 1434 | if style == 'nmake': 1435 | return 'nmake.in' 1436 | elif style == 'unix': 1437 | return ('unix_shr.in' if options.build_shared_lib else 'unix.in') 1438 | else: 1439 | raise Exception('Unknown makefile style "%s"' % (style)) 1440 | 1441 | # First delete the build tree, if existing 1442 | try: 1443 | if options.clean_build_tree: 1444 | shutil.rmtree(build_config.build_dir) 1445 | except OSError as e: 1446 | if e.errno != errno.ENOENT: 1447 | logging.error('Problem while removing build dir: %s' % (e)) 1448 | 1449 | for dir in build_config.build_dirs: 1450 | try: 1451 | os.makedirs(dir) 1452 | except OSError as e: 1453 | if e.errno != errno.EEXIST: 1454 | logging.error('Error while creating "%s": %s' % (dir, e)) 1455 | 1456 | makefile_template = os.path.join( 1457 | options.makefile_dir, 1458 | choose_makefile_template(template_vars['makefile_style'])) 1459 | 1460 | logging.debug('Using makefile template %s' % (makefile_template)) 1461 | 1462 | templates_to_proc = { 1463 | makefile_template: template_vars['makefile_path'] 1464 | } 1465 | 1466 | def templates_to_use(): 1467 | yield (options.build_data, 'buildh.in', 'build.h') 1468 | yield (options.build_data, 'botan.doxy.in', 'botan.doxy') 1469 | 1470 | if options.os != 'windows': 1471 | yield (options.build_data, 'botan.pc.in', build_config.pkg_config_file()) 1472 | yield (options.build_data, 'botan-config.in', build_config.config_shell_script()) 1473 | 1474 | if options.os == 'windows': 1475 | yield (options.build_data, 'innosetup.in', 'botan.iss') 1476 | 1477 | if options.boost_python: 1478 | yield (options.makefile_dir, 'python.in', 'Makefile.python') 1479 | 1480 | for (template_dir, template, sink) in templates_to_use(): 1481 | source = os.path.join(template_dir, template) 1482 | if template_dir == options.build_data: 1483 | sink = os.path.join(build_config.build_dir, sink) 1484 | templates_to_proc[source] = sink 1485 | 1486 | for (template, sink) in templates_to_proc.items(): 1487 | try: 1488 | f = open(sink, 'w') 1489 | f.write(process_template(template, template_vars)) 1490 | finally: 1491 | f.close() 1492 | 1493 | link_method = choose_link_method(options.link_method) 1494 | logging.info('Using %s to link files into build directory' % (link_method)) 1495 | 1496 | def link_headers(header_list, type, dir): 1497 | logging.debug('Linking %d %s header files in %s' % ( 1498 | len(header_list), type, dir)) 1499 | 1500 | for header_file in header_list: 1501 | try: 1502 | portable_symlink(header_file, dir, link_method) 1503 | except OSError as e: 1504 | if e.errno != errno.EEXIST: 1505 | logging.error('Error linking %s into %s: %s' % ( 1506 | header_file, dir, e)) 1507 | 1508 | link_headers(build_config.public_headers, 'public', 1509 | build_config.botan_include_dir) 1510 | 1511 | link_headers(build_config.build_internal_headers, 'internal', 1512 | build_config.internal_include_dir) 1513 | 1514 | """ 1515 | Generate Amalgamation 1516 | """ 1517 | def generate_amalgamation(build_config): 1518 | def ending_with_suffix(suffix): 1519 | def predicate(val): 1520 | return val.endswith(suffix) 1521 | return predicate 1522 | 1523 | def strip_header_goop(header_name, contents): 1524 | header_guard = re.compile('^#define BOTAN_.*_H__$') 1525 | 1526 | while len(contents) > 0: 1527 | if header_guard.match(contents[0]): 1528 | contents = contents[1:] 1529 | break 1530 | 1531 | contents = contents[1:] 1532 | 1533 | if len(contents) == 0: 1534 | raise Exception("No header guard found in " + header_name) 1535 | 1536 | while contents[0] == '\n': 1537 | contents = contents[1:] 1538 | 1539 | while contents[-1] == '\n': 1540 | contents = contents[0:-1] 1541 | if contents[-1] == '#endif\n': 1542 | contents = contents[0:-1] 1543 | 1544 | return contents 1545 | 1546 | botan_include = re.compile('#include $') 1547 | std_include = re.compile('#include <([^/\.]+)>$') 1548 | 1549 | class Amalgamation_Generator: 1550 | def __init__(self, input_list): 1551 | 1552 | self.included_already = set() 1553 | self.all_std_includes = set() 1554 | 1555 | self.file_contents = {} 1556 | for f in sorted(input_list): 1557 | contents = strip_header_goop(f, open(f).readlines()) 1558 | self.file_contents[os.path.basename(f)] = contents 1559 | 1560 | self.contents = '' 1561 | for name in self.file_contents: 1562 | self.contents += ''.join(list(self.header_contents(name))) 1563 | 1564 | self.header_includes = '' 1565 | for std_header in self.all_std_includes: 1566 | self.header_includes += '#include <%s>\n' % (std_header) 1567 | self.header_includes += '\n' 1568 | 1569 | def header_contents(self, name): 1570 | name = name.replace('internal/', '') 1571 | 1572 | if name in self.included_already: 1573 | return 1574 | 1575 | self.included_already.add(name) 1576 | 1577 | if name not in self.file_contents: 1578 | return 1579 | 1580 | for line in self.file_contents[name]: 1581 | match = botan_include.search(line) 1582 | if match: 1583 | for c in self.header_contents(match.group(1)): 1584 | yield c 1585 | else: 1586 | match = std_include.search(line) 1587 | 1588 | if match and match.group(1) != 'functional': 1589 | self.all_std_includes.add(match.group(1)) 1590 | else: 1591 | yield line 1592 | 1593 | amalg_basename = 'botan_all' 1594 | 1595 | header_name = '%s.h' % (amalg_basename) 1596 | 1597 | botan_h = open(header_name, 'w') 1598 | 1599 | pub_header_amalag = Amalgamation_Generator(build_config.public_headers) 1600 | 1601 | amalg_header = """/* 1602 | * Botan %s Amalgamation 1603 | * (C) 1999-2011 Jack Lloyd and others 1604 | * 1605 | * Distributed under the terms of the Botan license 1606 | */ 1607 | """ % (build_config.version_string) 1608 | 1609 | botan_h.write(amalg_header) 1610 | 1611 | botan_h.write(""" 1612 | #ifndef BOTAN_AMALGAMATION_H__ 1613 | #define BOTAN_AMALGAMATION_H__ 1614 | 1615 | """) 1616 | 1617 | botan_h.write(pub_header_amalag.header_includes) 1618 | botan_h.write(pub_header_amalag.contents) 1619 | botan_h.write("\n#endif\n") 1620 | 1621 | internal_header_amalag = Amalgamation_Generator( 1622 | [s for s in build_config.internal_headers 1623 | if s.find('asm_macr_') == -1]) 1624 | 1625 | botan_cpp = open('%s.cpp' % (amalg_basename), 'w') 1626 | 1627 | botan_cpp.write(amalg_header) 1628 | 1629 | botan_cpp.write('\n#include "%s"\n' % (header_name)) 1630 | 1631 | botan_cpp.write(internal_header_amalag.header_includes) 1632 | botan_cpp.write(internal_header_amalag.contents) 1633 | 1634 | for src in build_config.sources: 1635 | if src.endswith('.S'): 1636 | continue 1637 | 1638 | contents = open(src).readlines() 1639 | for line in contents: 1640 | if botan_include.search(line): 1641 | continue 1642 | else: 1643 | botan_cpp.write(line) 1644 | 1645 | """ 1646 | Test for the existence of a program 1647 | """ 1648 | def have_program(program): 1649 | 1650 | def exe_test(path, program): 1651 | exe_file = os.path.join(path, program) 1652 | 1653 | if os.path.exists(exe_file) and os.access(exe_file, os.X_OK): 1654 | logging.debug('Found program %s in %s' % (program, path)) 1655 | return True 1656 | else: 1657 | return False 1658 | 1659 | exe_suffixes = ['', '.exe'] 1660 | 1661 | for path in os.environ['PATH'].split(os.pathsep): 1662 | for suffix in exe_suffixes: 1663 | if exe_test(path, program + suffix): 1664 | return True 1665 | 1666 | return False 1667 | 1668 | """ 1669 | Main driver 1670 | """ 1671 | def main(argv = None): 1672 | if argv is None: 1673 | argv = sys.argv 1674 | 1675 | logging.basicConfig(stream = sys.stdout, 1676 | format = '%(levelname) 7s: %(message)s') 1677 | 1678 | options = process_command_line(argv[1:]) 1679 | 1680 | def log_level(): 1681 | if options.verbose: 1682 | return logging.DEBUG 1683 | if options.quiet: 1684 | return logging.WARNING 1685 | return logging.INFO 1686 | 1687 | logging.getLogger().setLevel(log_level()) 1688 | 1689 | logging.debug('%s invoked with options "%s"' % ( 1690 | argv[0], ' '.join(argv[1:]))) 1691 | 1692 | logging.debug('Platform: OS="%s" machine="%s" proc="%s"' % ( 1693 | platform.system(), platform.machine(), platform.processor())) 1694 | 1695 | if options.os == "java": 1696 | raise Exception("Jython detected: need --os and --cpu to set target") 1697 | 1698 | options.base_dir = os.path.dirname(argv[0]) 1699 | options.src_dir = os.path.join(options.base_dir, 'src') 1700 | 1701 | options.build_data = os.path.join(options.src_dir, 'build-data') 1702 | options.makefile_dir = os.path.join(options.build_data, 'makefile') 1703 | 1704 | (modules, archinfo, ccinfo, osinfo) = load_info_files(options) 1705 | 1706 | if options.compiler is None: 1707 | if options.os == 'windows': 1708 | if have_program('g++') and not have_program('cl'): 1709 | options.compiler = 'gcc' 1710 | else: 1711 | options.compiler = 'msvc' 1712 | else: 1713 | options.compiler = 'gcc' 1714 | logging.info('Guessing to use compiler %s (use --cc to set)' % ( 1715 | options.compiler)) 1716 | 1717 | if options.os is None: 1718 | options.os = platform.system().lower() 1719 | 1720 | if re.match('^cygwin_.*', options.os): 1721 | logging.debug("Converting '%s' to 'cygwin'", options.os) 1722 | options.os = 'cygwin' 1723 | 1724 | if options.os == 'windows' and options.compiler == 'gcc': 1725 | logging.warning('Detected GCC on Windows; use --os=cygwin or --os=mingw?') 1726 | 1727 | logging.info('Guessing target OS is %s (use --os to set)' % (options.os)) 1728 | 1729 | if options.compiler not in ccinfo: 1730 | raise Exception('Unknown compiler "%s"; available options: %s' % ( 1731 | options.compiler, ' '.join(sorted(ccinfo.keys())))) 1732 | 1733 | if options.os not in osinfo: 1734 | 1735 | def find_canonical_os_name(os): 1736 | for (name, info) in osinfo.items(): 1737 | if os in info.aliases: 1738 | return name 1739 | return os # not found 1740 | 1741 | options.os = find_canonical_os_name(options.os) 1742 | 1743 | if options.os not in osinfo: 1744 | raise Exception('Unknown OS "%s"; available options: %s' % ( 1745 | options.os, ' '.join(sorted(osinfo.keys())))) 1746 | 1747 | if options.cpu is None: 1748 | (options.arch, options.cpu) = guess_processor(archinfo) 1749 | logging.info('Guessing target processor is a %s/%s (use --cpu to set)' % ( 1750 | options.arch, options.cpu)) 1751 | else: 1752 | cpu_from_user = options.cpu 1753 | (options.arch, options.cpu) = canon_processor(archinfo, options.cpu) 1754 | logging.info('Canonicalizized --cpu=%s to %s/%s' % ( 1755 | cpu_from_user, options.arch, options.cpu)) 1756 | 1757 | logging.info('Target is %s-%s-%s-%s' % ( 1758 | options.compiler, options.os, options.arch, options.cpu)) 1759 | 1760 | cc = ccinfo[options.compiler] 1761 | 1762 | # Kind of a hack... 1763 | options.extra_flags = '' 1764 | if options.compiler == 'gcc': 1765 | 1766 | def get_gcc_version(gcc_bin): 1767 | try: 1768 | gcc_proc = subprocess.Popen( 1769 | gcc_bin.split(' ') + ['-dumpversion'], 1770 | stdout=subprocess.PIPE, 1771 | stderr=subprocess.PIPE, 1772 | universal_newlines=True) 1773 | 1774 | (stdout, stderr) = gcc_proc.communicate() 1775 | 1776 | if gcc_proc.returncode != 0: 1777 | logging.warning("GCC returned non-zero result %s" % (stderr)) 1778 | return None 1779 | 1780 | gcc_version = stdout.strip() 1781 | 1782 | logging.info('Detected gcc version %s' % (gcc_version)) 1783 | return gcc_version 1784 | except OSError: 1785 | logging.warning('Could not execute %s for version check' % (gcc_bin)) 1786 | return None 1787 | 1788 | def is_64bit_arch(arch): 1789 | if arch.endswith('64') or arch in ['alpha', 's390x']: 1790 | return True 1791 | return False 1792 | 1793 | gcc_version = get_gcc_version(options.compiler_binary or cc.binary_name) 1794 | 1795 | if gcc_version: 1796 | 1797 | if not is_64bit_arch(options.arch) and not options.dumb_gcc: 1798 | matching_version = '(4\.[01234]\.)|(3\.[34]\.)|(2\.95\.[0-4])' 1799 | 1800 | if re.search(matching_version, gcc_version): 1801 | options.dumb_gcc = True 1802 | 1803 | versions_without_tr1 = '(4\.0\.)|(3\.[0-4]\.)|(2\.95\.[0-4])' 1804 | 1805 | if options.with_tr1 == None and \ 1806 | re.search(versions_without_tr1, gcc_version): 1807 | logging.info('Disabling TR1 support for this gcc, too old') 1808 | options.with_tr1 = 'none' 1809 | 1810 | versions_without_visibility = '(3\.[0-4]\.)|(2\.95\.[0-4])' 1811 | if options.with_visibility == None and \ 1812 | re.search(versions_without_visibility, gcc_version): 1813 | logging.info('Disabling DSO visibility support for this gcc, too old') 1814 | options.with_visibility = False 1815 | 1816 | if options.dumb_gcc is True: 1817 | logging.info('Setting -fpermissive to work around gcc bug') 1818 | options.extra_flags = ' -fpermissive' 1819 | 1820 | if options.with_visibility is None: 1821 | options.with_visibility = True 1822 | 1823 | if options.with_tr1 == None: 1824 | if cc.has_tr1: 1825 | logging.info('Assuming %s has TR1 (use --with-tr1=none to disable)' % ( 1826 | options.compiler)) 1827 | options.with_tr1 = 'system' 1828 | else: 1829 | options.with_tr1 = 'none' 1830 | 1831 | if options.with_sphinx is None: 1832 | if have_program('sphinx-build'): 1833 | logging.info('Found sphinx-build, will use it ' + 1834 | '(use --without-sphinx to disable)') 1835 | options.with_sphinx = True 1836 | 1837 | if options.via_amalgamation: 1838 | options.gen_amalgamation = True 1839 | 1840 | if options.gen_amalgamation: 1841 | if options.asm_ok: 1842 | logging.info('Disabling assembly code, cannot use in amalgamation') 1843 | options.asm_ok = False 1844 | 1845 | modules_to_use = choose_modules_to_use(modules, 1846 | archinfo[options.arch], 1847 | options) 1848 | 1849 | if not osinfo[options.os].build_shared: 1850 | if options.build_shared_lib: 1851 | logging.info('Disabling shared lib on %s' % (options.os)) 1852 | options.build_shared_lib = False 1853 | 1854 | build_config = BuildConfigurationInformation(options, modules_to_use) 1855 | build_config.public_headers.append( 1856 | os.path.join(build_config.build_dir, 'build.h')) 1857 | 1858 | template_vars = create_template_vars(build_config, options, 1859 | modules_to_use, 1860 | cc, 1861 | archinfo[options.arch], 1862 | osinfo[options.os]) 1863 | 1864 | # Performs the I/O 1865 | setup_build(build_config, options, template_vars) 1866 | 1867 | if options.gen_amalgamation: 1868 | generate_amalgamation(build_config) 1869 | 1870 | logging.info('Botan %s build setup is complete' % ( 1871 | build_config.version_string)) 1872 | 1873 | if __name__ == '__main__': 1874 | try: 1875 | main() 1876 | except Exception as e: 1877 | logging.error(str(e)) 1878 | #import traceback 1879 | #traceback.print_exc(file=sys.stderr) 1880 | sys.exit(1) 1881 | sys.exit(0) 1882 | -------------------------------------------------------------------------------- /NEncryptionKit/3rdparty/botan/doc/license.txt: -------------------------------------------------------------------------------- 1 | 2 | .. _license: 3 | .. highlight:: none 4 | 5 | License 6 | ======================================== 7 | 8 | Botan (http://botan.randombit.net/) is distributed under these terms:: 9 | 10 | Copyright (C) 1999-2011 Jack Lloyd 11 | 2001 Peter J Jones 12 | 2004-2007 Justin Karneges 13 | 2004 Vaclav Ovsik 14 | 2005 Matthew Gregan 15 | 2005-2006 Matt Johnston 16 | 2006 Luca Piccarreta 17 | 2007 Yves Jerschow 18 | 2007-2008 FlexSecure GmbH 19 | 2007-2008 Technische Universitat Darmstadt 20 | 2007-2008 Falko Strenzke 21 | 2007-2008 Martin Doering 22 | 2007 Manuel Hartl 23 | 2007 Christoph Ludwig 24 | 2007 Patrick Sona 25 | 2010 Olivier de Gaalon 26 | All rights reserved. 27 | 28 | Redistribution and use in source and binary forms, with or without 29 | modification, are permitted provided that the following conditions are 30 | met: 31 | 32 | 1. Redistributions of source code must retain the above copyright 33 | notice, this list of conditions, and the following disclaimer. 34 | 35 | 2. Redistributions in binary form must reproduce the above copyright 36 | notice, this list of conditions, and the following disclaimer in the 37 | documentation and/or other materials provided with the distribution. 38 | 39 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR 40 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 41 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, 42 | ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE 43 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 44 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 45 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 46 | BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 47 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 48 | OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 49 | IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 50 | -------------------------------------------------------------------------------- /NEncryptionKit/3rdparty/botan/readme.txt: -------------------------------------------------------------------------------- 1 | Botan 1.10.2, 2012-06-17 2 | http://botan.randombit.net/ 3 | 4 | Botan is a C++ class library for performing a wide variety of 5 | cryptographic operations. It is released under the 2 clause BSD 6 | license; see doc/license.txt for the specifics. You can file bugs in 7 | Bugzilla (http://bugs.randombit.net/) or by sending a report to the 8 | botan-devel mailing list. More information about the mailing list is 9 | at http://lists.randombit.net/mailman/listinfo/botan-devel/ 10 | 11 | You can find documentation online at http://botan.randombit.net/ as 12 | well as in the doc directory in the distribution. Several examples can 13 | be found in doc/examples as well. 14 | 15 | Jack Lloyd (lloyd@randombit.net) 16 | -------------------------------------------------------------------------------- /NEncryptionKit/NEncryptionKit.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2016-08-03T11:12:42 4 | # 5 | #------------------------------------------------- 6 | 7 | QT -= gui 8 | 9 | TARGET = NEncryptionKit 10 | TEMPLATE = lib 11 | 12 | DEFINES += NENCRYPTIONKIT_LIBRARY 13 | 14 | # 导入源码 15 | include($$PWD/NEncryptionKit_src.pri) 16 | 17 | # 设置版本信息 18 | RC_FILE += ./NEncryptionKit_resource.rc 19 | 20 | # 设定编译输出路径 21 | win32{ 22 | CONFIG += debug_and_release 23 | CONFIG(release, debug|release) { 24 | target_path = ./build_/dist 25 | } else { 26 | target_path = ./build_/debug 27 | } 28 | DESTDIR = ./../bin 29 | MOC_DIR = $$target_path/moc 30 | RCC_DIR = $$target_path/rcc 31 | OBJECTS_DIR = $$target_path/obj 32 | } 33 | 34 | # 输出编译套件信息 35 | message(Qt version: $$[QT_VERSION]) 36 | message(Qt is installed in $$[QT_INSTALL_PREFIX]) 37 | message(the NEncryptionKit will create in folder: $$target_path) 38 | -------------------------------------------------------------------------------- /NEncryptionKit/NEncryptionKit_inc.pri: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2016-08-03T11:12:42 4 | # 5 | #------------------------------------------------- 6 | 7 | INCLUDEPATH += $$PWD/inc/ \ 8 | 9 | LIBS += -L$$PWD/../bin/ -lNEncryptionKit 10 | -------------------------------------------------------------------------------- /NEncryptionKit/NEncryptionKit_resource.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daodaoliang/NEncryptionKit/ae70afce9cf6cf6dbce80a5eb027de64029eb094/NEncryptionKit/NEncryptionKit_resource.rc -------------------------------------------------------------------------------- /NEncryptionKit/NEncryptionKit_src.pri: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2016-08-03T11:12:42 4 | # 5 | #------------------------------------------------- 6 | 7 | # 引入源码 8 | SOURCES += $$PWD/src/nencryptionkit.cpp 9 | 10 | HEADERS += $$PWD/inc/nencryptionkit.h \ 11 | $$PWD/inc/nencryptionkit_global.h 12 | INCLUDEPATH += $$PWD/inc/ 13 | 14 | # 引入第三方源码 15 | include($$PWD/3rdparty/botan/botan.pri) 16 | INCLUDEPATH += $$PWD/3rdparty/botan/ 17 | -------------------------------------------------------------------------------- /NEncryptionKit/inc/nencryptionkit.h: -------------------------------------------------------------------------------- 1 | #ifndef NENCRYPTIONKIT_H 2 | #define NENCRYPTIONKIT_H 3 | 4 | /** 5 | * 加解密组件库 6 | * 作者: daodaoliang 7 | * 时间: 2016年8月05日 8 | * 版本: 1.0.1.0 9 | * 邮箱: daodaoliang@yeah.net 10 | */ 11 | 12 | #include "nencryptionkit_global.h" 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | using namespace std; 21 | 22 | /** 23 | * @brief The NEncryptionKit class 24 | * 数据的加解密、签名、校验等组件 25 | */ 26 | class NENCRYPTIONKITSHARED_EXPORT NEncryptionKit : public QObject 27 | { 28 | Q_OBJECT 29 | public: 30 | explicit NEncryptionKit(QObject *parent = 0); 31 | 32 | public: 33 | 34 | /** 35 | * @brief getMD5Hash 获取字符串的MD5散列值 36 | * @param param_data 待转换的数据 37 | * @return 转换后的散列值 38 | */ 39 | QString getMD5Hash(const QString ¶m_data); 40 | 41 | /** 42 | * @brief getSHAHash 获取字符串的SHA散列值 43 | * @param param_data 待转换的数据 44 | * @return 转换后的散列值 45 | */ 46 | QString getSHAHash(const QString ¶m_data); 47 | 48 | /** 49 | * @brief getByKaiser 获取采用凯撒机密的字符串 50 | * @param param_data 待加密的数据 51 | * @param param_key 加密秘钥 52 | * @return 是否加密成功 53 | */ 54 | bool getByKaiser(QString ¶m_data,qint8 param_key); 55 | 56 | /** 57 | * @brief createRSAKey 产生RSA密钥 58 | * @param paramPubKeyFile 公钥文件存储地址 59 | * @param paramPriKeyFile 私钥文件存储地址 60 | * @return 61 | */ 62 | bool createRSAKey(QString paramPubKeyFile, QString paramPriKeyFile); 63 | 64 | /** 65 | * @brief getEncryptByRSA 用RSA公钥进行加密 66 | * @param paramDataSource 需要被加密的数据 67 | * @param paramDataDest 加密后的数据 68 | * @param paramPubKey 公钥文件路径 69 | * @return 70 | */ 71 | bool getEncryptByRSA(QString paramDataSource, QByteArray ¶mDataDest, QString paramPubKeyPath); 72 | 73 | /** 74 | * @brief decryptionByRSA 用RSA私钥进行解密 75 | * @param paramDataSource 需要进行解密的数据 76 | * @param paramDataDest 解密后的数据 77 | * @param paramPriKeyPath 私钥文件路劲 78 | * @return 79 | */ 80 | bool decryptionByRSA(QByteArray paramDataSource, QString ¶mDataDest, QString paramPriKeyPath); 81 | 82 | /** 83 | * @brief getEncryByAES 用AES进行加密 84 | * @param paramSource 待加密字符串 85 | * @param paramDest 加密后的字符串 86 | * @return 是否解密成功 87 | */ 88 | bool getEncryByAES(QString paramSource, string ¶mDest); 89 | 90 | /** 91 | * @brief decryptByAES 用AES进行解密 92 | * @param paramSource 待解密字符串 93 | * @param paramDest 解密后的字符串 94 | * @return 是否解密成功 95 | */ 96 | bool decryptByAES(string paramSource, QString ¶mDest); 97 | 98 | /** 99 | * @brief setPassword 设置加密的密钥 100 | * @param param_password 密钥 101 | */ 102 | void setPassword(QString param_password); 103 | 104 | /** 105 | * @brief setSalt 设置加密盐 106 | * @param param_salt 107 | */ 108 | void setSalt(QString param_salt); 109 | 110 | private: 111 | 112 | /** 113 | * @brief mPassword 密码 114 | */ 115 | QString mPassword; 116 | }; 117 | 118 | #endif // NENCRYPTIONKIT_H 119 | 120 | -------------------------------------------------------------------------------- /NEncryptionKit/inc/nencryptionkit_global.h: -------------------------------------------------------------------------------- 1 | #ifndef NENCRYPTIONKIT_GLOBAL_H 2 | #define NENCRYPTIONKIT_GLOBAL_H 3 | 4 | #include 5 | 6 | #if defined(NENCRYPTIONKIT_LIBRARY) 7 | # define NENCRYPTIONKITSHARED_EXPORT Q_DECL_EXPORT 8 | #else 9 | # define NENCRYPTIONKITSHARED_EXPORT Q_DECL_IMPORT 10 | #endif 11 | 12 | #endif // NENCRYPTIONKIT_GLOBAL_H 13 | -------------------------------------------------------------------------------- /NEncryptionKit/src/nencryptionkit.cpp: -------------------------------------------------------------------------------- 1 | #include "nencryptionkit.h" 2 | #include 3 | #include 4 | #include 5 | #include "botan.h" 6 | 7 | using namespace Botan; 8 | 9 | NEncryptionKit::NEncryptionKit(QObject *parent):QObject(parent) 10 | { 11 | //设置默认密码 12 | mPassword = getSHAHash("iamdaodaoliang(nami_salt)"); 13 | } 14 | 15 | QString NEncryptionKit::getMD5Hash(const QString ¶m_data) 16 | { 17 | return QString(QCryptographicHash::hash(param_data.toLocal8Bit(),QCryptographicHash::Md5).toHex()); 18 | } 19 | 20 | QString NEncryptionKit::getSHAHash(const QString ¶m_data) 21 | { 22 | return QString(QCryptographicHash::hash(param_data.toLocal8Bit(),QCryptographicHash::Sha3_512).toHex()); 23 | } 24 | 25 | bool NEncryptionKit::getByKaiser(QString ¶m_data, qint8 param_key) 26 | { 27 | if(param_data.isEmpty()){ 28 | return false; 29 | } 30 | for(int temp_index = 0; temp_index != param_data.size();++temp_index){ 31 | char tempChar = param_data.at(temp_index).toLatin1(); 32 | int tempValue = 0; 33 | if(tempChar >= 0x30 && tempChar <= 0x39){ 34 | tempValue = (tempChar - '0' + param_key); 35 | tempChar = (tempValue >= 0) ? (tempValue % 10 + '0') : (tempValue % 10 + 0x3a); 36 | } else if (tempChar >= 0x41 && tempChar <= 0x5a) { 37 | tempValue = (tempChar - 'A' + param_key); 38 | tempChar = (tempValue >= 0) ? (tempValue % 26 + 'A') : (tempValue % 26 + 0x5b); 39 | } else if (tempChar >= 0x61 && tempChar <= 0x7a) { 40 | tempValue = (tempChar - 'a' + param_key); 41 | tempChar = (tempValue >= 0) ? (tempValue % 26 + 'a') : (tempValue % 26 + 0x7b); 42 | } 43 | param_data[temp_index] = QChar(tempChar); 44 | } 45 | return true; 46 | } 47 | 48 | bool NEncryptionKit::createRSAKey(QString paramPubKeyFile, QString paramPriKeyFile) 49 | { 50 | try{ 51 | Botan::AutoSeeded_RNG rng; 52 | Botan::RSA_PrivateKey privateKey(rng, 1024); 53 | QString temp_pri(Botan::X509::PEM_encode(privateKey).c_str()); 54 | QString temp_pub(Botan::PKCS8::PEM_encode(privateKey).c_str()); 55 | 56 | if(QFile::exists(paramPriKeyFile)){ 57 | QFile::remove(paramPriKeyFile); 58 | } 59 | QFile innerFile(paramPriKeyFile); 60 | if(innerFile.open(QFile::ReadWrite)){ 61 | innerFile.write(temp_pub.toLocal8Bit()); 62 | innerFile.flush(); 63 | } 64 | innerFile.close(); 65 | 66 | if(QFile::exists(paramPubKeyFile)){ 67 | QFile::remove(paramPubKeyFile); 68 | } 69 | QFile innerFile_1(paramPubKeyFile); 70 | if(innerFile_1.open(QFile::ReadWrite)){ 71 | innerFile_1.write(temp_pri.toLocal8Bit()); 72 | innerFile_1.flush(); 73 | } 74 | innerFile_1.close(); 75 | return true; 76 | } catch(Exception &e){ 77 | qDebug()< en = enc.encrypt(paramDataSource.toStdString().c_str(), paramDataSource.toStdString().size(), rng); 89 | QByteArray temp; 90 | for (uint i = 0; i < en.size(); i++) 91 | { 92 | temp[i] = en[i]; 93 | } 94 | paramDataDest = temp; 95 | return true; 96 | } catch(Exception &e){ 97 | qDebug()< temp_mem; 109 | temp_mem.resize(paramDataSource.size()); 110 | for(uint i = 0; i< paramDataSource.size(); ++i){ 111 | temp_mem[i] = paramDataSource[i]; 112 | } 113 | SecureVector re = dec.decrypt(temp_mem,temp_mem.size()); 114 | QByteArray temp; 115 | for (uint i = 0; i < re.size(); i++) 116 | { 117 | temp[i] = re[i]; 118 | } 119 | paramDataDest = QString(temp); 120 | return true; 121 | } catch(Exception &e){ 122 | qDebug()<process(mPassword.toStdString()); 133 | SecureVector raw_iv = hash->process('0'+ mPassword.toStdString()); 134 | InitializationVector iv(raw_iv, 16); 135 | Pipe pipe(get_cipher("AES-128/CBC/PKCS7", key, iv, ENCRYPTION)); 136 | pipe.process_msg(paramSource.toStdString()); 137 | string output=pipe.read_all_as_string(); 138 | paramDest = output; 139 | return true; 140 | } 141 | catch(Exception &e) 142 | { 143 | qDebug()<process(mPassword.toStdString()); 154 | SecureVector raw_iv = hash->process('0'+ mPassword.toStdString()); 155 | InitializationVector iv(raw_iv, 16); 156 | Pipe pipe(get_cipher("AES-128/CBC/PKCS7", key, iv, DECRYPTION)); 157 | pipe.process_msg(paramSource); 158 | string output=pipe.read_all_as_string(); 159 | paramDest = QString::fromStdString(output); 160 | return true; 161 | } 162 | catch(Exception &e) 163 | { 164 | qDebug()<