├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── common.mk ├── cshared ├── Makefile ├── cdir.h ├── cdir_win.c ├── clog.c ├── clog.h ├── cmem.h ├── copts.c ├── copts.h ├── cring.c ├── cring.h ├── cserialize.c ├── cserialize.h ├── cshared.vcxproj ├── cstr.c ├── cstr.h ├── e4c_lite.c ├── e4c_lite.h └── tests │ └── test_copts.c ├── fitsec.sln ├── libfitsec ├── Makefile ├── fitsec.h ├── fitsec_crypt.h ├── libfitsec.vcxproj ├── plugins │ └── fitsec_openssl.c └── src │ ├── fitsec_cert.c │ ├── fitsec_certhash.c │ ├── fitsec_crypt.c │ ├── fitsec_engine.c │ ├── fitsec_error.c │ ├── fitsec_error.h │ ├── fitsec_i.h │ ├── fitsec_region.c │ ├── fitsec_types.c │ ├── fitsec_types.h │ ├── fitsec_unstats.h │ └── khash.h ├── tests ├── Makefile ├── mkgmtime.c ├── mkgmtime.h ├── test_engine.c └── test_engine.vcxproj └── tools └── mkunstats ├── fitsec_unstats.h └── mkunstats.c /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | # Object files 3 | *.o 4 | *.ko 5 | *.obj 6 | *.elf 7 | 8 | # Precompiled Headers 9 | *.gch 10 | *.pch 11 | 12 | # Libraries 13 | *.lib 14 | *.a 15 | *.la 16 | *.lo 17 | 18 | # Shared objects (inc. Windows DLLs) 19 | *.dll 20 | *.so 21 | *.so.* 22 | *.dylib 23 | 24 | # Executables 25 | *.exe 26 | *.out 27 | *.app 28 | *.i*86 29 | *.x86_64 30 | *.hex 31 | 32 | # Debug files 33 | *.dSYM/ 34 | *.su 35 | 36 | #Visual studio 37 | *.sdf 38 | *.opensdf 39 | *.suo 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: tests 2 | clean: 3 | -make -C tests clean 4 | -make -C libfitsec clean 5 | -make -C cshared clean 6 | 7 | tests: libfitsec FORCE 8 | make -C tests all 9 | 10 | libfitsec: cshared FORCE 11 | make -C libfitsec all 12 | 13 | cshared: FORCE 14 | make -C cshared all 15 | FORCE: -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FITSec - The ETSI TS 103 097 implementation 2 | 3 | ## Overview ## 4 | 5 | The library provides the security envelop to be used for the Intelligent Transport Systems G5 communication based on 6 | [ETSI EN 302 636-4-1](http://www.etsi.org/deliver/etsi_en/302600_302699/3026360401/01.02.01_60/en_3026360401v010201p.pdf). 7 | The library is fully conformed to [ETSI TS 103 097 v1.2.1](http://www.etsi.org/deliver/etsi_ts/103000_103099/103097/01.02.01_60/ts_103097v010201p.pdf) 8 | with optional support of non-published v1.2.5. 9 | The new version [ETSI TS 103 097 v1.3.1](http://www.etsi.org/deliver/etsi_ts/103000_103099/103097/01.03.01_60/ts_103097v010301p.pdf) is published at October 2017. It is ASN.1 based and the library is not (yet?) compatible with it. 10 | 11 | The library is written in plain C in cross-platform manner and has been compiled and tested in Linux(gcc) and Windows(mingw32,cygwin and Visual C 13) environments. 12 | 13 | It implements the plugin interface to use various crypto engines. For the moment, only the [OpenSSL](https://www.openssl.org/) engine is implemented, but support of HSM (Hardware Security Module) is in the plan. 14 | Please see the _fitsec_openssl.c_ for the example of plugin implementation. 15 | 16 | ## User API ## 17 | The main API is defined in the [_fitsec.h_](https://github.com/DanyaFilatov/FITSec/blob/master/libfitsec/fitsec.h) header. 18 | I really invite you to have a look into this file to understand the meaning of various parameters. 19 | 20 | ### Initialization ### 21 | 1. First of all, the instance of the engine must be created using the __*FitSec_New*__. 22 | This function takes a configuration strucutre as a parameter. 23 | This configuration strucure can be initialized using the __*FitSecConfig_InitDefault*__. 24 | 25 | 2. Install all necessary certificates using function __*FitSec_InstallCertificate*__. 26 | All certificates installed by this function will be considered as trusted. Any types of certificates can be installed. 27 | Authorization tickets shall be followed by the correspondent private keys. 28 | (Note: This behavior will be changed in order to support HSM). 29 | 30 | ### Outgoing Messages ### 31 | Processing of outgoing messages is splitted to two stages: 32 | - preparation of the message header 33 | - signing and/or encryption of the message 34 | 35 | In order to optimize the memory manipulatoin efforts, all operations are done directly in the buffer provided by the facility layer. 36 | This buffer can be passed later to the transport layer. The size of the buffer shall be well enough to contain all security headers, 37 | certificates and the payload of the message. 38 | The GeoNetworking Security Header takes place between Basic Header and Common Header elements in GeoNetworking message strucure. 39 | So, to send a secured GN message, facylity layer shall perform following actions: 40 | - prepare Basic GN Header 41 | - call __*FitSec_PrepareMessage*__ to prepare Security header 42 | - fill the payload buffer with the payload data, starting from Common GN Header, update the payload size field in message information structure. 43 | (Note: Please don't spend too much time in this stage because it can violate the CAM signing rules.) 44 | - call __*FitSec_SignMessage*__ to encrypt and/or sign the message. 45 | 46 | Please see the [_fitsec.h_](libfitsec/fitsec.h) for function descriptions. 47 | 48 | #### Preparation of message header #### 49 | As soon as GeoNetworking layer prepared the Basic Header, it can call __*FitSec_PrepareMessage*__ to create the Security Header element and to put it into outgoing buffer. 50 | This function must be called with following parameters: 51 | - buffer and maximum buffer length. This parameter shall point to the outgoing memory buffer right after the Basic Header element. 52 | - message information strucuture, containing: 53 | - payload type (signed, encrypted, etc.) 54 | - current position (not needed for CAM) 55 | - the timestamp, when the last GPS fix has been occured. 56 | - Application ID and SSP bits, describing the content of the message. The ITS AID list can be found on [ISO TS17419 V2016-02-09: "ITS-AID_AssignedNumbers")(http://standards.iso.org/iso/ts/17419/TS17419%20Assigned%20Numbers/TS17419_ITS-AID_AssignedNumbers.pdf) 57 | 58 | The function creates the ITS Security Header in the provided buffer and fill the message information structure with: 59 | - payload offset - the pointer to the memory buffer where facility layer can put the payload 60 | - max payload size - the maximum size of payload buffer. Facility layer shall put the actual payload size there 61 | - certificate to be used - it takes into account provided ITS AID, SSP, timestamp and location 62 | - signer type (certificate, digest, chain). 63 | 64 | The function can override the payload type if it is required by the security profile. The CAM and DENM security profile requires the payload to be signed but not encrypted. 65 | 66 | The data in the message information strucure will be used on the next stage, so please keep it unchanged, excepting of payload size. 67 | 68 | The function returns the offset in the buffer to copy the payload or -1 if case of some error. The error id and error description are provided in the message information strucure. 69 | 70 | Please see the [_fitsec.h_](libfitsec/fitsec.h) for function descriptions. 71 | 72 | #### Preparing of payload #### 73 | The GeoNetworking layer needs to create the Common Header and, optionally the Extended Header elements, and to put the facility layer payload into the outgoing buffer. 74 | 75 | The total length of these elements shall be set in the payload size field in the message information strucure. 76 | 77 | #### Signing and/or encrypting of the message #### 78 | 79 | When payload creation is well done, the message could be encrypted and/or signed, depending of the payload type. 80 | The GN layer must call __*FitSec_SignMessage*__ to perform these tasks. 81 | This functions takes same parameters as the __*FitSec_PrepareMessage*__. 82 | 83 | _Note: encryption is not implemented yet. See Limitations section_ 84 | 85 | The function returns the full size of secured packet or -1 in case of error. The error id and error description are provided in the message information strucure. 86 | 87 | ### Incoming Messages ### 88 | 89 | The function __*FitSec_Verify*__ can be used to verify the incoming message signature. 90 | 91 | It will fill the content of the message information structure: 92 | - payload, payload size and payload type 93 | - position and generation time 94 | - signer info type and signing certificate (if any) 95 | - Application ID and SSP bits of certificate. 96 | 97 | Function verifies the message signature, returns true or false and fill the error id and the error description elements in the message information structure. 98 | 99 | It is up to facility layer to check the conformance of the incoming message with correspondent SSP bitfield and to take or doesn't take it into account. 100 | 101 | The function __*FitSec_Decrypt*__ will be implemented soon to be able to use encrypted messages. 102 | 103 | ## Limitations ## 104 | - The library doesn't support encryption for the moment. 105 | 106 | ## Author ## 107 | The library was created in 2015-2016 by Denis Filatov (danya.filatov()gmail.com) in order to validate the ETSI's ITS security test suite. The library is free for non-commercial and not-for-profit usage, otherwise please contact the author. 108 | -------------------------------------------------------------------------------- /common.mk: -------------------------------------------------------------------------------- 1 | export LANG=en_US 2 | ALL_CONFIGURATIONS := POSIX WIN32 3 | .PHONY: all clean tests docs cleandocs distr DUMMY 4 | 5 | CSHAREDDIR ?= cshared 6 | CXMLDIR ?= cxml 7 | 8 | ifeq ($(ARCH),) 9 | ARCH = $(shell gcc -dumpmachine) 10 | GCC := gcc 11 | else 12 | GCC := $(addprefix $(addsuffix -,$(ARCH)), gcc) 13 | endif 14 | 15 | ifneq ($(findstring w32,$(ARCH)),) 16 | packages := $(filter-out readline threads, $(packages)) 17 | CFG += WIN32 18 | else 19 | CFG += POSIX 20 | ifeq ($(findstring cygwin,$(ARCH)),) 21 | cflags += -fPIC 22 | endif 23 | endif 24 | 25 | cflags += -Wall 26 | 27 | ifeq ($(DEBUG),) 28 | DEBUG=no 29 | endif 30 | 31 | ifeq ($(DEBUG),yes) 32 | cflags += -g -O0 33 | defines += DEBUG 34 | dsuffix = -d 35 | else 36 | defines += NDEBUG 37 | cflags += -O2 38 | endif 39 | 40 | ifneq ($(filter readline, $(packages)),) 41 | defines += USE_READLINE 42 | libs += -lreadline 43 | endif 44 | 45 | ifneq ($(filter dmalloc, $(packages)),) 46 | defines += DMALLOC DMALLOC_FUNC_CHECK 47 | libs += -ldmalloc 48 | dsuffix = -dmalloc 49 | endif 50 | 51 | ifneq ($(filter thread, $(packages)),) 52 | defines += USE_THREADS 53 | libs += -lpthread 54 | endif 55 | 56 | ifneq ($(filter profile, $(packages)),) 57 | cflags += -pg 58 | endif 59 | 60 | ifneq ($(filter openssl, $(packages)),) 61 | ifneq ($(findstring mingw32,$(ARCH)),) 62 | includes += C:/OpenSSL/Win32/include 63 | libs += C:/OpenSSL/Win32/lib/MinGW/libeay32.a C:/OpenSSL/Win32/lib/MinGW/ssleay32.a 64 | else 65 | libs += -lssl -lcrypto 66 | endif 67 | endif 68 | 69 | ifneq ($(filter cxml, $(packages)),) 70 | predirs += $(CXMLDIR) 71 | includes += $(CXMLDIR) 72 | endif 73 | 74 | ifneq ($(filter cshared, $(packages)),) 75 | predirs += $(CSHAREDDIR) 76 | includes += $(CSHAREDDIR) 77 | endif 78 | 79 | ifeq ($(testdir), ) 80 | testdir := tests 81 | endif 82 | 83 | includes += $(foreach cfg,$(CFG),$(includes-$(cfg))) 84 | defines += $(foreach cfg,$(CFG),$(defines-$(cfg))) 85 | libs += $(foreach cfg,$(CFG),$(libs-$(cfg))) 86 | sources += $(foreach cfg,$(CFG),$(sources-$(cfg))) 87 | headers += $(foreach cfg,$(CFG),$(headers-$(cfg))) 88 | tests += $(foreach cfg,$(CFG),$(tests-$(cfg))) 89 | distfiles += $(foreach cfg,$(CFG),$(distfiles-$(cfg))) 90 | predirs += $(foreach cfg,$(CFG),$(predirs-$(cfg))) 91 | postdirs += $(foreach cfg,$(CFG),$(postdirs-$(cfg))) 92 | 93 | tests := $(addprefix $(addsuffix /,$(testdir)),$(tests)) 94 | sources := $(addprefix $(addsuffix /,$(srcdir)),$(sources)) 95 | headers := $(addprefix $(addsuffix /,$(incdir)),$(headers)) 96 | 97 | cflags += $(addprefix -I, $(includes)) $(addprefix -D, $(defines)) 98 | 99 | ifeq ($(BUILDROOT),) 100 | BUILDROOT = . 101 | endif 102 | 103 | outdir := $(BUILDROOT)/$(ARCH)$(dsuffix) 104 | objdir := $(outdir)/$(PROJECT) 105 | objects := $(patsubst %.c, $(objdir)/%.o, $(sources)) 106 | testbins := $(patsubst %.c, $(outdir)/%, $(tests)) 107 | dirs := $(objdir) $(outdir)/tests 108 | 109 | alibnames := $(patsubst %, $(outdir)/lib%.a, $(alibs)) 110 | solibnames := $(patsubst %, $(outdir)/lib%.so, $(solibs)) 111 | binnames := $(patsubst %, $(outdir)/%, $(bins)) 112 | 113 | ldflags += $(patsubst %, -L%, $(outdir) $(libdirs)) 114 | 115 | ifneq ($(filter cxml, $(packages)),) 116 | libs += $(outdir)/libcxml.a 117 | endif 118 | 119 | ifneq ($(filter cshared, $(packages)),) 120 | libs += $(outdir)/libcshared.a 121 | endif 122 | 123 | 124 | all: $(dirs) $(predirs) $(alibnames) $(solibnames) $(binnames) $(postdirs) 125 | 126 | tests: all $(testbins) 127 | 128 | $(predirs) $(postdirs): DUMMY 129 | $(MAKE) -C $@ BUILDROOT=$(realpath $(BUILDROOT)) DEBUG=$(DEBUG) 130 | 131 | $(alibnames): $(outdir)/lib%.a : $(objects) 132 | ar rcs $@ $^ 133 | 134 | $(solibnames): $(outdir)/lib%.so : $(objects) 135 | $(GCC) $(cflags) -shared $(ldflags) -o $@ $^ $(csharedlib) $(libs) 136 | 137 | $(binnames): $(outdir)/% : $(objects) 138 | $(GCC) $(cflags) $(ldflags) -o $@ $^ $(csharedlib) $(libs) 139 | 140 | $(testbins): $(alibnames) 141 | $(testbins): $(outdir)/tests/% : tests/%.c 142 | $(GCC) $(cflags) -o $@ $< $(alibnames) $(libs) 143 | 144 | $(dirs): 145 | mkdir -p $@ 146 | 147 | $(objects): $(objdir)/%.o: %.c 148 | @mkdir -p $(dir $@) 149 | $(GCC) $(cflags) -o $@ -MMD -MF $(objdir)/$*.d -c $< 150 | 151 | clean: 152 | rm -rf $(alibnames) $(solibnames) $(binnames) $(testbins) $(objects) 153 | 154 | distfiles += $(wildcard Makefile $(DOXYFILE)) 155 | dist: 156 | -rm -rf $(PROJECT) $(PROJECT)-$(shell date -u '+%Y%m%d').tar.gz 157 | mkdir $(PROJECT) 158 | cp --parents $(sources) $(headers) $(distfiles) $(addprefix tests/, $(tests)) $(PROJECT) 159 | tar -zcvf $(PROJECT)-$(shell date -u '+%Y%m%d').tar.gz $(PROJECT) 160 | rm -rf $(PROJECT) 161 | # tar -zcvf $(PROJECT)-$(shell date -u '+%Y%m%d').tar.gz $(sources) $(headers) $(distfiles) $(addprefix tests/, $(tests)) 162 | 163 | ifneq (,$(DOXYFILE)) 164 | docs: $(DOXYFILE) 165 | doxygen $(DOXYFILE) 166 | 167 | cleandocs: 168 | rm -rf doc/html 169 | endif 170 | 171 | include $(wildcard $(addsuffix /*.d, $(objdir))) 172 | -------------------------------------------------------------------------------- /cshared/Makefile: -------------------------------------------------------------------------------- 1 | PROJECTROOT = .. 2 | BUILDROOT = ../build/ 3 | PROJECT = cshared 4 | DEBUG = yes 5 | testdir = tests 6 | 7 | alibs = $(PROJECT) 8 | solibs = $(PROJECT) 9 | 10 | sources := copts.c cserialize.c cstr.c cring.c e4c_lite.c 11 | sources-WIN32 := cdir_win.c 12 | headers := copts.h cserialize.h cstr.h cdir.h cring.h e4c_lite.h 13 | tests := test_copts.c 14 | 15 | include ../common.mk 16 | -------------------------------------------------------------------------------- /cshared/cdir.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | ###################################################################### 3 | ## 4 | ## Created by: Denis Filatov 5 | ## Date : 10.11.2005 6 | ## 7 | ## Copyleft (c) 2003 - 2015 8 | ## This code is provided under the CeCill-C license agreement. 9 | ###################################################################### 10 | *********************************************************************/ 11 | #ifndef cdir_h 12 | #define cdir_h 13 | #include "cstr.h" 14 | #include "cserialize.h" 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif 18 | 19 | typedef struct cdir_t cdir_t; 20 | enum { 21 | e_cdir_recursive = 1, 22 | e_cdir_nofiles = 4, 23 | e_cdir_nodirs = 8, 24 | }; 25 | 26 | typedef struct { 27 | const char * path; 28 | const char * fname; 29 | int flags; 30 | uint64_t size; 31 | }cdir_stat_t; 32 | 33 | cdir_t * cdir_open(const pchar_t * path, const char * mask, int flags); 34 | void cdir_close(cdir_t * dir); 35 | cdir_t * cdir_rewind(cdir_t * dir); 36 | const cdir_stat_t * cdir_next(cdir_t * dir); 37 | 38 | int cdir_glob(const char * mask, const char * fname); 39 | #ifdef __cplusplus 40 | } 41 | #endif 42 | #endif 43 | 44 | -------------------------------------------------------------------------------- /cshared/cdir_win.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | ###################################################################### 3 | ## 4 | ## Created by: Denis Filatov 5 | ## Date : 10.11.2005 6 | ## 7 | ## Copyleft (c) 2003 - 2015 8 | ## This code is provided under the CeCill-C license agreement. 9 | ###################################################################### 10 | *********************************************************************/ 11 | #define _CRT_SECURE_NO_WARNINGS 12 | #include "cdir.h" 13 | #include "cmem.h" 14 | #include "cstr.h" 15 | #include 16 | 17 | 18 | struct cdir_t { 19 | WIN32_FIND_DATA fd; 20 | HANDLE h; 21 | int flags; 22 | char * path; 23 | char * fname; 24 | cdir_stat_t st; 25 | }; 26 | 27 | static void _cdir_apply_filter(cdir_t * dir) 28 | { 29 | do { 30 | if (dir->fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { 31 | if (strcmp(".", dir->fd.cFileName) && strcmp("..", dir->fd.cFileName)){ 32 | if (0 == (dir->flags & e_cdir_nodirs)) return; 33 | } 34 | } 35 | else { 36 | if (0 == (dir->flags & e_cdir_nofiles)) return; 37 | } 38 | //skip this file 39 | } while (FindNextFile(dir->h, &dir->fd)); 40 | FindClose(dir->h); 41 | dir->h = INVALID_HANDLE_VALUE; 42 | } 43 | 44 | cdir_t * cdir_open(const pchar_t * path, const char * mask, int flags) 45 | { 46 | cdir_t * dir; 47 | int plen = path ? pchar_len(path) : 0; 48 | dir = cnew(cdir_t); 49 | dir->path = pchar_alloc(plen + MAX_PATH + 1); 50 | pchar_cpy(dir->path, path); 51 | while (plen > 0 && (dir->path[plen - 1] == '/' || dir->path[plen - 1] == '\\'))plen--; 52 | if (plen > 0) { 53 | dir->path[plen] = '\\'; 54 | dir->fname = dir->path + plen + 1; 55 | } 56 | else{ 57 | dir->fname = dir->path; 58 | } 59 | dir->flags = flags; 60 | if (mask == NULL) mask = "*"; 61 | strcpy(dir->fname, mask); 62 | dir->h = FindFirstFile(dir->path, &dir->fd); 63 | if (INVALID_HANDLE_VALUE == dir->h){ 64 | cfree(dir); 65 | return NULL; 66 | } 67 | _cdir_apply_filter(dir); 68 | dir->st.path = dir->path; 69 | dir->st.fname = dir->fname; 70 | return dir; 71 | } 72 | 73 | void cdir_close(cdir_t * dir) 74 | { 75 | if(dir){ 76 | if(dir->h != INVALID_HANDLE_VALUE){ 77 | FindClose(dir->h); 78 | } 79 | cfree(dir); 80 | } 81 | } 82 | 83 | cdir_t * cdir_rewind(cdir_t * dir) 84 | { 85 | if(dir){ 86 | if(dir->h != INVALID_HANDLE_VALUE){ 87 | FindClose(dir->h); 88 | } 89 | *dir->fname = 0; 90 | dir->h = FindFirstFile(dir->path, &dir->fd); 91 | if(INVALID_HANDLE_VALUE == dir->h){ 92 | cfree(dir); 93 | dir = NULL; 94 | } 95 | } 96 | return dir; 97 | } 98 | 99 | const cdir_stat_t* cdir_next(cdir_t * dir) 100 | { 101 | if (dir && dir->h != INVALID_HANDLE_VALUE){ 102 | pchar_cpy(dir->fname, dir->fd.cFileName); 103 | dir->st.size = dir->fd.nFileSizeHigh; 104 | dir->st.size = (dir->st.size << 32) | dir->fd.nFileSizeLow; 105 | if (FindNextFile(dir->h, &dir->fd)){ 106 | _cdir_apply_filter(dir); 107 | }else { 108 | FindClose(dir->h); 109 | dir->h = INVALID_HANDLE_VALUE; 110 | } 111 | return &dir->st; 112 | } 113 | return NULL; 114 | } 115 | -------------------------------------------------------------------------------- /cshared/clog.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | ###################################################################### 3 | ## 4 | ## Created by: Denis Filatov 5 | ## Date : 10.11.2005 6 | ## 7 | ## Copyleft (c) 2003 - 2015 8 | ## This code is provided under the CeCill-C license agreement. 9 | ###################################################################### 10 | *********************************************************************/ 11 | #include 12 | #include 13 | #include 14 | #include "clog.h" 15 | 16 | static int _clog_level = CLOG_INFO; 17 | static FILE * _clog_out[CLOG_LASTLEVEL]; 18 | static const char * _clog_lnames[CLOG_LASTLEVEL] = { 19 | "FATAL", 20 | "ERROR", 21 | "WARNING", 22 | "INFO", 23 | "DEBUG", 24 | }; 25 | 26 | static int _clog_out_initialized = 0; 27 | 28 | static void _clog_out_initialize(void) 29 | { 30 | int i; 31 | _clog_out[CLOG_FATAL] = stderr; 32 | _clog_out[CLOG_ERROR] = stderr; 33 | _clog_out[CLOG_WARNING] = stderr; 34 | for(i=CLOG_INFO; i= 0 && level <= CLOG_DEBUG){ 48 | _clog_level = level; 49 | } 50 | } 51 | const char * clog_level_name(int const level) 52 | { 53 | const char * ret = NULL; 54 | if(level < CLOG_LASTLEVEL) 55 | ret = _clog_lnames[level]; 56 | return ret ? ret : CLOG_DEFAULT_LEVEL_NAME; 57 | } 58 | 59 | void clog_set_level_name(int const level, const char * const name) 60 | { 61 | if(level < CLOG_LASTLEVEL) 62 | _clog_lnames[level] = name; 63 | } 64 | 65 | void clog_set_output(int const level, void * const out) 66 | { 67 | if(0 == _clog_out_initialized){ 68 | _clog_out_initialize(); 69 | } 70 | if(level < 0){ 71 | int i; 72 | for(i=0; i= sizeof(_clog_out)/sizeof(_clog_out[0])){ 92 | out = _clog_out[sizeof(_clog_out)/sizeof(_clog_out[0]) - 1]; 93 | }else{ 94 | out = _clog_out[level]; 95 | } 96 | } 97 | if(out){ 98 | va_start(ap, format); 99 | vfprintf(out, format, ap); 100 | va_end(ap); 101 | { 102 | int l = strlen(format); 103 | if(l == 0 || format[l-1]!= '\n'){ 104 | fprintf(out, "\n"); 105 | } 106 | } 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /cshared/clog.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | ###################################################################### 3 | ## 4 | ## Created by: Denis Filatov 5 | ## Date : 10.11.2005 6 | ## 7 | ## Copyleft (c) 2003 - 2015 8 | ## This code is provided under the CeCill-C license agreement. 9 | ###################################################################### 10 | *********************************************************************/ 11 | #ifndef clog_h 12 | #define clog_h 13 | enum{ 14 | CLOG_FATAL=0, 15 | CLOG_ERROR, 16 | CLOG_WARNING, 17 | CLOG_INFO, 18 | CLOG_DEBUG, 19 | 20 | CLOG_LASTLEVEL 21 | }; 22 | 23 | int clog_level(void); 24 | void clog_set_level(int const level); 25 | const char * clog_level_name(int const level); 26 | void clog_set_level_name(int const level, const char * const name); 27 | void clog_set_output(int const level, void * const out); 28 | 29 | #define CLOG_DEFAULT_LEVEL_NAME "" 30 | 31 | #define STRMODULE(M) #M 32 | #define XSTRMODULE(M) STRMODULE(M) 33 | 34 | #define clog_flm(F, SMODULE, LEVEL, FORMAT, ...) clog_fprintf(F, LEVEL, "%10.10s: %7.7s: " FORMAT, SMODULE, clog_level_name(LEVEL), ##__VA_ARGS__) 35 | #define clog_lm(SMODULE,LEVEL,FORMAT, ...) clog_flm((void*)0, SMODULE, LEVEL, FORMAT, ##__VA_ARGS__) 36 | #define clog_fl(F,LEVEL,FORMAT, ...) clog_flm(F, XSTRMODULE(__MODULE__), LEVEL, FORMAT, ##__VA_ARGS__) 37 | #define clog_l(LEVEL,FORMAT, ...) clog_flm((void*)0, XSTRMODULE(__MODULE__), LEVEL, FORMAT, ##__VA_ARGS__) 38 | 39 | #define clog_fatal(FORMAT, ...) clog_l(CLOG_FATAL, FORMAT, ##__VA_ARGS__) 40 | #define clog_error(FORMAT, ...) clog_l(CLOG_ERROR, FORMAT, ##__VA_ARGS__) 41 | #define clog_warning(FORMAT, ...) clog_l(CLOG_WARNING, FORMAT, ##__VA_ARGS__) 42 | #define clog_info(FORMAT, ...) clog_l(CLOG_INFO, FORMAT, ##__VA_ARGS__) 43 | #define clog_debug(FORMAT, ...) clog_l(CLOG_DEBUG, FORMAT, ##__VA_ARGS__) 44 | 45 | #define fclog_fatal(F,FORMAT, ...) clog_fl(F, CLOG_FATAL, FORMAT, ##__VA_ARGS__) 46 | #define fclog_error(F,FORMAT, ...) clog_fl(F, CLOG_ERROR, FORMAT, ##__VA_ARGS__) 47 | #define fclog_warning(F,FORMAT, ...) clog_fl(F, CLOG_WARNING, FORMAT, ##__VA_ARGS__) 48 | #define fclog_info(F,FORMAT, ...) clog_fl(F, CLOG_INFO, FORMAT, ##__VA_ARGS__) 49 | #define fclog_debug(F,FORMAT, ...) clog_fl(F, CLOG_DEBUG, FORMAT, ##__VA_ARGS__) 50 | 51 | #define mclog_fatal(MODULE, FORMAT, ...) clog_lm(#MODULE, CLOG_FATAL, FORMAT, ##__VA_ARGS__) 52 | #define mclog_error(MODULE, FORMAT, ...) clog_lm(#MODULE, CLOG_ERROR, FORMAT, ##__VA_ARGS__) 53 | #define mclog_warning(MODULE, FORMAT, ...) clog_lm(#MODULE, CLOG_WARNING, FORMAT, ##__VA_ARGS__) 54 | #define mclog_info(MODULE, FORMAT, ...) clog_lm(#MODULE, CLOG_INFO, FORMAT, ##__VA_ARGS__) 55 | #define mclog_debug(MODULE, FORMAT, ...) clog_lm(#MODULE, CLOG_DEBUG, FORMAT, ##__VA_ARGS__) 56 | 57 | #define fmclog_fatal(F, MODULE, FORMAT, ...) clog_flm(F, #MODULE, CLOG_FATAL, FORMAT, ##__VA_ARGS__) 58 | #define fmclog_error(F, MODULE, FORMAT, ...) clog_flm(F, #MODULE, CLOG_ERROR, FORMAT, ##__VA_ARGS__) 59 | #define fmclog_warning(F, MODULE, FORMAT, ...) clog_flm(F, #MODULE, CLOG_WARNING, FORMAT, ##__VA_ARGS__) 60 | #define fmclog_info(F, MODULE, FORMAT, ...) clog_flm(F, #MODULE, CLOG_INFO, FORMAT, ##__VA_ARGS__) 61 | #define fmclog_debug(F, MODULE, FORMAT, ...) clog_flm(F, #MODULE, CLOG_DEBUG, FORMAT, ##__VA_ARGS__) 62 | 63 | void clog_fprintf(void * const f, int const level, const char * format, ...); 64 | 65 | #undef __CLOG_MODULE 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /cshared/cmem.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | ###################################################################### 3 | ## 4 | ## Created by: Denis Filatov 5 | ## Date : 10.11.2005 6 | ## 7 | ## Copyleft (c) 2003 - 2015 8 | ## This code is provided under the CeCill-C license agreement. 9 | ###################################################################### 10 | *********************************************************************/ 11 | #ifndef cmem_h 12 | #define cmem_h 13 | #include 14 | #include 15 | #define callocate(N) malloc(N) 16 | #define callocate0(N) calloc(1,N) 17 | #define cfree(P) free(P) 18 | #define cnew(T) (T*)callocate(sizeof(T)) 19 | #define cnew0(T) (T*)callocate0(sizeof(T)) 20 | typedef void(cdestructor_fn)(void*); 21 | 22 | #if defined(__GNUC__) 23 | #define cfetch_and_add(P,X) __sync_fetch_and_add(P, X) 24 | #define cfetch_and_sub(P,X) __sync_fetch_and_sub(P, X) 25 | #define cadd_and_fetch(P,X) __sync_add_and_fetch(P, X) 26 | #define csub_and_fetch(P,X) __sync_sub_and_fetch(P, X) 27 | #define cfetch_and_inc(P) cfetch_and_add(P,1) 28 | #define cfetch_and_dec(P) cfetch_and_sub(P,1) 29 | #define cinc_and_fetch(P) cadd_and_fetch(P,1) 30 | #define cdec_and_fetch(P) csub_and_fetch(P,1) 31 | 32 | #elif defined (_MSC_VER) 33 | #include 34 | #define cfetch_and_add(P,X) (InterlockedAddNoFence(P,X)-X) 35 | #define cfetch_and_sub(P,X) (InterlockedAddNoFence(P,-X)+X) 36 | #define cadd_and_fetch(P,X) InterlockedAddNoFence(P,X) 37 | #define csub_and_fetch(P,X) InterlockedAddNoFence(P,-X) 38 | #define cfetch_and_inc(P) (InterlockedIncrementNoFence(P)-1) 39 | #define cfetch_and_dec(P) (InterlockedDecrementNoFence(P)+1) 40 | #define cinc_and_fetch(P) InterlockedIncrementNoFence(P) 41 | #define cdec_and_fetch(P) InterlockedDecrementNoFence(P) 42 | #ifndef __cplusplus 43 | #define inline _inline 44 | #endif 45 | #endif 46 | 47 | __inline static void * cmemdup(const void * const ptr, int size) { 48 | void * p; 49 | if (size > 0){ 50 | p = callocate(size); 51 | if (p && ptr) { 52 | memcpy(p, ptr, size); 53 | } 54 | } 55 | else{ 56 | p = NULL; 57 | } 58 | return p; 59 | } 60 | 61 | __inline static void * _cretain(void*p, int*prcntr) { 62 | if (*prcntr != 0){ 63 | cinc_and_fetch(prcntr); 64 | } 65 | return p; 66 | } 67 | __inline static void _crelease(void*p, int*prcntr, void * destr) { 68 | if (*prcntr != 0){ 69 | if(0 == cdec_and_fetch(prcntr)){ 70 | if (destr) ((cdestructor_fn *)destr)(p); 71 | else free(p); 72 | } 73 | } 74 | } 75 | 76 | #if defined(__GNUC__) 77 | #define cretain(S) (__typeof__(S)*)_cretain(S, &(S)->_rcntr) 78 | #elif defined (_MSC_VER) 79 | #define cretain(S) _cretain(S, &(S)->_rcntr) 80 | #endif 81 | 82 | #define crelease(S,D) _crelease(S, &(S)->_rcntr, D) 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /cshared/copts.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | ###################################################################### 3 | ## 4 | ## Created by: Denis Filatov 5 | ## Date : 10.11.2005 6 | ## 7 | ## C command line arguments and simple config file parser 8 | ## 9 | ## Copyleft (c) 2003 - 2007 10 | ## This code is provided under the CeCill-C license agreement. 11 | ###################################################################### 12 | *********************************************************************/ 13 | #ifndef copts_h 14 | #define copts_h 15 | #include 16 | 17 | #ifdef __cplusplus 18 | extern "C" { 19 | #endif 20 | 21 | /** @defgroup COPTS copts - Programm line option processing. 22 | * @{ */ 23 | 24 | #ifndef DOXYGEN 25 | typedef struct copt_t copt_t; 26 | typedef enum coptflag_t coptflag_t; 27 | typedef enum coptype_t coptype_t; 28 | typedef enum copterr_t copterr_t; 29 | #endif 30 | /** @enum coptype_t 31 | * Option types definitions. 32 | */ 33 | enum coptype_t{ 34 | COPT_BOOL , /**< Boolean option. Doesn't require arguments.*/ 35 | COPT_BOOLI, /**< Inverted Boolean option. Doesn't require arguments. */ 36 | COPT_LONG , /**< Requires for long argument */ 37 | COPT_ULONG, /**< Requires for unsigned long argument */ 38 | COPT_SHORT, /**< Requires for short (16 bit) argument */ 39 | COPT_USHORT, /**< Requires for unsigned short argument */ 40 | COPT_CHAR , /**< Requires for char or unsigned char argument */ 41 | COPT_STR , /**< Requires for string (const char *) arguments */ 42 | COPT_HOST, /**< Requires for string (const char *) arguments. Checks url syntax. */ 43 | COPT_PATH, /**< Requires for string (const pchar_t *) arguments. */ 44 | COPT_STRLIST, /**< Requires for string list argument (const char *[]) 45 | * Every time when this opion will be occuren in argv 46 | * the value will be assigned to given pointer and 47 | * this pointer will be incremented. */ 48 | COPT_STRENUM, /**< Requires for one of the string in the array given by vptr) 49 | * Array of strings must be terminated by NULL pointer. 50 | * After option found the vptr pointer will point 51 | * to the element corresponding to the argument */ 52 | COPT_CFGFILE, /**< Requires for string (const pchar_t *) arguments. 53 | * Treat it as config file name and load if found. 54 | * If one or more config file options are exists in copt_t list 55 | * this options will be executed before any other options parsing */ 56 | COPT_HELP, /**< Does't require argument. 57 | * If this option is occured in command line parsing will be 58 | * terminated imediate and COPT_EHELP will be returned */ 59 | 60 | 61 | COPT_TYPE_MASK = 0x00FF, /**< Option type mask. For internal usage. */ 62 | COPT_CALLBACK = 0x4000, /**< Mask. Can be or-ed with any other option. 63 | * That's mean treat vptr as a callback addres to call 64 | * when option is occured */ 65 | COPT_CONFIG = 0x8000, /**< Mask. Can be or-ed with any other option. 66 | * That's mean this option can be reached from config file 67 | * and have to be writen to.*/ 68 | 69 | COPT_END = 0xFFFF, /**< End of options. 70 | * If vptr is not NULL, treat it as callback to call for unknown 71 | * options and non-option values */ 72 | }; 73 | 74 | #define COPT_INT COPT_LONG 75 | #define COPT_UINT COPT_ULONG 76 | #define COPT_IBOOL COPT_BOOLI 77 | 78 | /** Main options item. 79 | * Have to be used to define options items. 80 | * Short and long options can be defined. 81 | * Possible options notations: 82 | * - Boolean options: 83 | * - -o 84 | * - --option 85 | * - Other types except of boolean: 86 | * - -o value 87 | * - -o=value 88 | * - --option=value 89 | */ 90 | struct copt_t 91 | { 92 | const char* sopts; /**< Short options. */ 93 | const char* lopt; /**< Long option. */ 94 | const coptype_t type; /**< Option type ( see @ref coptype_t ). */ 95 | void* vptr; /**< Option variable pointer. */ 96 | const char* helpstr; /**< Option help string. */ 97 | }; 98 | 99 | /** 100 | * Execute option parser. 101 | * @param argc Command line parameters count (from arguments of main() for example). 102 | * @param argv Array of command line parameters. 103 | * @param flags Configuration flags ( @ref coptflag_t ). 104 | * @param opts Array of possible options. Must be finished by item with COPT_END type. 105 | * @return
  • On success returns the index of the first option argument in the arguments array.
  • On error returns negative index of the invalid option in the arguments array.
106 | */ 107 | int coptions(int argc, char* argv[], int flags, copt_t* opts); 108 | 109 | /** Get enum index from the option variable. 110 | * @param opts @ref copt_t array. 111 | * @param idx Index of the enum option in the array. 112 | * @param ptr The initial value of the @a vptr field of the opion array item. 113 | * @return the integer enum value of the selected item. 114 | */ 115 | #define copts_enum_value(opts,idx,ptr) \ 116 | ((const char **)((opts)[idx]).vptr) - ((const char **)(ptr)) 117 | 118 | /** 119 | * Load options config file. 120 | * @param filename File path to load. 121 | * @param section If not NULL then try to find the last occurance of the 122 | * given section or load the file complet. 123 | * @param flags Configuration flags ( see @ref coptflag_t ). 124 | * @param opts The Array of possible option records. Must be finished 125 | * by the item with COPT_END type. 126 | * @return 127 |
  • On success returns 0.
  • On error returns negative line number of the invalid expression.
128 | */ 129 | int coptions_load(const char* filename, const char * section, int flags, copt_t* const opts); 130 | 131 | /** 132 | * Save current options to the file 133 | */ 134 | int coptions_save(const char* filename, const copt_t* const opts); 135 | 136 | /** 137 | * Save current options to already opened file 138 | */ 139 | int coptions_fsave(FILE * fd, const copt_t* const opts); 140 | 141 | /** 142 | * Generate and print the help page. 143 | * @param fd File descriptor to print the resulting help page. 144 | * @param prgname Application name. Can be taken from argv[0]. 145 | * @param opt Options array. 146 | * @param usagestr The string to print before option list. 147 | * @param header Help page header. 148 | * @param footer Help page footer. 149 | 150 | */ 151 | void coptions_help_ex(FILE * fd, const char * prgname, int flags, copt_t* opt, const char* usagestr, 152 | const char* header, const char* footer); 153 | /** The lite version of the @ref coptions_help_ex. 154 | * @param fd File descriptor to print the resulting help page. 155 | * @param prgname Application name. Can be taken from argv[0]. 156 | * @param opt Options array. 157 | * @param usagestr The string to print before option list. 158 | */ 159 | #define coptions_help(fd,prgname,flags,opt,usagestr) \ 160 | coptions_help_ex(fd,prgname,flags,opt,usagestr,NULL,NULL) 161 | 162 | /** Wild value definition */ 163 | typedef union{ 164 | int v_boolean; 165 | signed short v_short; 166 | unsigned short v_ushort; 167 | signed long v_long; 168 | unsigned long v_ulong; 169 | char v_char; 170 | char * v_str; 171 | }copt_value_t; 172 | 173 | /** The type of callback function to be called for the option having 174 | @ref COPT_CALLBACK bit set in the @e type field of the @ref copt_t structure. 175 | 176 | These functions must return zero if option was successfully processed, 177 | @ref COPT_EHELP to generate option help string or negative value when 178 | some error was occured. 179 | @param opt The current item of the options array. 180 | @param option String option given. 181 | @param value Pointer to the option value. 182 | */ 183 | 184 | typedef int copt_callback(const copt_t * opt, const char * option, const copt_value_t * value); 185 | 186 | /** Inverted Boolean True. */ 187 | #define IBOOL_YES ((void*)-1) 188 | 189 | /** @enum coptflag_t 190 | Option flag mask values. 191 | */ 192 | enum coptflag_t 193 | { 194 | COPT_DEFAULT = 0x0000, /**< No special flags given. */ 195 | COPT_NOAUTOHELP = 0x0001, /**< Does not provide automatic help messages. */ 196 | COPT_NOCONFIG = 0x0002, /**< Does not search for config files. */ 197 | COPT_NOREORDER = 0x0004, /**< Does not reorder command line array. */ 198 | COPT_NOERR_MSG = 0x0010, /**< Be silent. */ 199 | COPT_NOERR_UNKNOWN = 0x0020, /**< Treat unknown options as non-option args.*/ 200 | COPT_NOERR_ARG = 0x0040, /**< Does not produce an error if the required 201 | option's argument is omited or have 202 | incompatible type. */ 203 | COPT_NOERR = 0x0070, /**< Does not produce any errors. */ 204 | COPT_ERR_CONFIG = 0x0080, /**< Does not produce config errors. */ 205 | COPT_NOHELP_MSG = 0x0100, /**< Does not print help messages. */ 206 | COPT_HELP_NOVALUES = 0x0200, /**< Does not print default values. */ 207 | }; 208 | 209 | /** @{ 210 | @ref coptions return codes. 211 | */ 212 | /** Help option (-h or --help) vaw invoked. Need to print help page.*/ 213 | #define COPT_EHELP ((int)(0x80000001)) 214 | /** Some error was occured.*/ 215 | #define COPT_ERROR ((int)(0x80000002)) 216 | #define COPT_ERC(rc) (rc < 0 && 0==(rc & 0x8000000)) 217 | /**@}*/ 218 | 219 | /** @} */ 220 | 221 | /** 222 | * @example test_copts.c 223 | */ 224 | 225 | #ifdef __cplusplus 226 | } 227 | #endif 228 | 229 | #endif 230 | -------------------------------------------------------------------------------- /cshared/cring.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | ###################################################################### 3 | ## 4 | ## Created by: Denis Filatov 5 | ## Date : 10.11.2005 6 | ## 7 | ## Copyleft (c) 2003 - 2015 8 | ## This code is provided under the CeCill-C license agreement. 9 | ###################################################################### 10 | *********************************************************************/ 11 | #include "cring.h" 12 | #include "cmem.h" 13 | #include 14 | void _cring_init( cring_t * const r ) 15 | { 16 | r->next = r; 17 | r->prev = r; 18 | } 19 | 20 | cring_t * _cring_erase( cring_t * const x ) 21 | { 22 | cring_t * n = x->next; 23 | cring_t * p = x->prev; 24 | n->prev = p; 25 | p->next = n; 26 | x->next = x; 27 | x->prev = x; 28 | return n; 29 | } 30 | 31 | cring_t * _cring_insert_after( cring_t * const r, cring_t * const i) 32 | { 33 | cring_t * n = r->next; 34 | i->prev = r; 35 | r->next = i; 36 | i->next = n; 37 | n->prev = i; 38 | return n; 39 | } 40 | 41 | cring_t * _cring_insert_before( cring_t * const r, cring_t * const i) 42 | { 43 | cring_t * p = r->prev; 44 | i->next = r; 45 | r->prev = i; 46 | i->prev = p; 47 | p->next = i; 48 | return p; 49 | } 50 | 51 | cring_t * _cring_insert_ring_after( cring_t * const p, cring_t * const b) 52 | { 53 | cring_t *n, *e; 54 | 55 | if(b->next == b){ 56 | return _cring_insert_after(p, b); 57 | } 58 | 59 | n = p->next; 60 | e = b->prev; 61 | 62 | p->next = b; 63 | b->prev = p; 64 | n->prev = e; 65 | e->next = n; 66 | return n; 67 | } 68 | 69 | cring_t * _cring_insert_ring_before( cring_t * const n, cring_t * const b) 70 | { 71 | cring_t *p, *e; 72 | 73 | if(b->next == b){ 74 | return _cring_insert_before(n, b); 75 | } 76 | p = n->prev; 77 | e = b->prev; 78 | 79 | p->next = b; 80 | b->prev = p; 81 | n->prev = e; 82 | e->next = n; 83 | return p; 84 | } 85 | 86 | cring_t * _cring_erase_ring( cring_t * const f, cring_t * const l) 87 | { 88 | cring_t *p, *n; 89 | 90 | if(f == l){ 91 | return _cring_erase(f); 92 | } 93 | 94 | p = f->prev; 95 | n = l->next; 96 | 97 | f->prev = l; 98 | l->next = f; 99 | 100 | p->next = n; 101 | n->prev = p; 102 | return n; 103 | } 104 | 105 | int cring_is_empty( cring_t * const r ) 106 | { 107 | return r->next == r; 108 | } 109 | 110 | void cring_cleanup(cring_t * const r, void * const fn_destructor) 111 | { 112 | while(r->next != r){ 113 | cring_t * x = r->next; 114 | _cring_erase(x); 115 | if(fn_destructor){ 116 | ((void(*)(void*))fn_destructor)(x); 117 | } 118 | } 119 | } 120 | 121 | cring_t * _cring_insert_sorted(cring_t * const r, cring_t * const n, cring_compare_fn * const fn_compare) 122 | { 123 | cring_t * i = r->next; 124 | for (; i != r; i = i->next){ 125 | int x = fn_compare(i, n); 126 | if (x == 0) 127 | return i; 128 | if (x > 0) /* i > n */ 129 | break; 130 | } 131 | _cring_insert_before(i, n); 132 | return n; 133 | } 134 | 135 | cring_t * _cring_find_sorted(cring_t * const r, cring_t * const n, cring_compare_fn * const fn_compare) 136 | { 137 | cring_t * i = r->next; 138 | for (; i != r; i = i->next){ 139 | int x = fn_compare(i, n); 140 | if (x == 0) 141 | return i; 142 | if (x > 0) /* i > n */ 143 | break; 144 | } 145 | return NULL; 146 | } 147 | 148 | cring_t * cring_zerase( cring_t * * const root, cring_t * const r ) 149 | { 150 | if(r->next == r){ 151 | *root = NULL; 152 | return r; 153 | } 154 | 155 | if(*root == r){ 156 | *root = r->next; 157 | } 158 | return _cring_erase(r); 159 | } 160 | 161 | cring_t * cring_zinsert_after (cring_t * * const root, cring_t * const i) 162 | { 163 | if(*root == NULL) { 164 | *root = i; 165 | return i; 166 | } 167 | return _cring_insert_ring_after(*root, i); 168 | } 169 | 170 | cring_t * cring_zinsert_before(cring_t * * const root, cring_t * const i) 171 | { 172 | if(*root == NULL) { 173 | *root = i; 174 | return i; 175 | } 176 | return _cring_insert_ring_before(*root, i); 177 | } 178 | 179 | cring_t * cring_zerase_ring( cring_t * * const root, cring_t * const f, cring_t * const l) 180 | { 181 | cring_t *i, *ret; 182 | if(f->prev == l){ 183 | /* remove full ring */ 184 | *root = NULL; 185 | return NULL; 186 | } 187 | 188 | ret = _cring_erase_ring( f, l); 189 | 190 | /* need to check if *root occurs in erased space */ 191 | i = f; 192 | do{ 193 | if(i == *root){ 194 | *root = ret->prev; 195 | break; 196 | } 197 | if(i == l){ 198 | break; 199 | } 200 | i=i->next; 201 | }while(1); 202 | return ret; 203 | } 204 | 205 | void cring_zcleunup( cring_t * * const root, void * const fn_destructor) 206 | { 207 | cring_t * r = *root; 208 | if(r){ 209 | *root = NULL; 210 | do{ 211 | cring_t * n = r->next; 212 | _cring_erase(r); 213 | if(fn_destructor){ 214 | ((void(*)(void*))fn_destructor)(r); 215 | } 216 | if(r == n){ 217 | break; 218 | } 219 | r=n; 220 | }while(1); 221 | } 222 | } 223 | 224 | 225 | static cring_t __xcring_pool = {&__xcring_pool, &__xcring_pool}; 226 | 227 | xcring_t * xcring_new (void * const data) 228 | { 229 | xcring_t * r; 230 | if(__xcring_pool.next == &__xcring_pool){ 231 | int i; 232 | /* preallocate PREALLOC_D items */ 233 | r = callocate(sizeof(xcring_t)*XRING_PREALLOC); 234 | if(NULL == r) return NULL; 235 | for(i = 0; inext = r; 237 | r->prev = r; 238 | r->data = NULL; 239 | _cring_insert_after( &__xcring_pool, (cring_t *) r); 240 | } 241 | /* use last allocated item */ 242 | r->next = r; 243 | r->prev = r; 244 | }else{ 245 | r = (xcring_t *)__xcring_pool.next; 246 | _cring_erase( __xcring_pool.next ); 247 | } 248 | r->data = data; 249 | return r; 250 | } 251 | 252 | void xcring_free(xcring_t * const r, void * const fn_destructor) 253 | { 254 | if(r->data){ 255 | if(fn_destructor){ 256 | ((void(*)(void*))fn_destructor)(r->data); 257 | } 258 | r->data = NULL; 259 | } 260 | _cring_insert_after( &__xcring_pool, (cring_t *) r); 261 | } 262 | 263 | void xcring_cleanup(cring_t * const root, void * const fn_destructor) 264 | { 265 | while(!cring_is_empty(root)){ 266 | xcring_t * r = (xcring_t *)root->next; 267 | _cring_erase(root->next); 268 | xcring_free(r, fn_destructor); 269 | } 270 | } 271 | 272 | xcring_t * xcring_enqueue(cring_t * const root, void * const data) 273 | { 274 | xcring_t * r = xcring_new (data); 275 | _cring_insert_before(root, (cring_t*)r); 276 | return r; 277 | } 278 | 279 | void * xcring_dequeue(cring_t * const root) 280 | { 281 | void * data; 282 | xcring_t * r; 283 | 284 | if(root->next == root){ 285 | return NULL; 286 | } 287 | 288 | r = (xcring_t*)root->next; 289 | _cring_erase((cring_t*)r); 290 | data=r->data; 291 | r->data = NULL; 292 | _cring_insert_after( &__xcring_pool, (cring_t *) r); 293 | return data; 294 | } 295 | 296 | void * xcring_find (cring_t * const root, void * const pattern, 297 | int(*comparator)(const void * const pattern, 298 | const void * const data)) 299 | { 300 | xcring_t * r = (xcring_t *)root->next; 301 | for(;r!=(xcring_t *)root; r=r->next){ 302 | if(0==comparator(pattern, r->data)){ 303 | return r->data; 304 | } 305 | } 306 | return NULL; 307 | } 308 | 309 | -------------------------------------------------------------------------------- /cshared/cring.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | ###################################################################### 3 | ## 4 | ## Created by: Denis Filatov 5 | ## Date : 10.11.2005 6 | ## 7 | ## Copyleft (c) 2003 - 2015 8 | ## This code is provided under the CeCill-C license agreement. 9 | ###################################################################### 10 | *********************************************************************/ 11 | #ifndef cring_h 12 | #define cring_h 13 | 14 | /** @defgroup CRING Double-Linked Rings. 15 | * @{ 16 | The @ref cring_t structure it is the easiest way to organize rounded 17 | double-linked lists of any data items. Insertion and removing of items 18 | are very lightweight operations. Rings are usefull for any types of 19 | queues, stacks and other types of data storage does not need the index-based 20 | access to the items. 21 | 22 | Every ring item have two pointers to the next and previous ones. This 23 | structure can be embedded to the data item structure at the begining or 24 | in any position (see @ref cring_cast). 25 | 26 | Here we have 3 data items inserted to the ring, headed by @c items member of 27 | Container structure. 28 | 29 | @code 30 | +==============+ +----->+===========+<--------+ 31 | I Container I | I Data item I | 32 | I structure I | I cring_t I | 33 | I I | I {next}--I-----+ | 34 | I . . . I | +---I---{prev} I | | 35 | I I | | I . . . I | | 36 | Icring_t items I<-|--+ +===========+ +----->+===========+ 37 | I {next}-I--+ | | | I Data item I 38 | I {prev}-I---+ | | | I cring_t I 39 | I I | | | +--I---{prev} I 40 | I . . . I | | +===========+<-----------I---{next} I 41 | I I +---->I Data item I | I . . . I 42 | I I | I cring_t I | +===========+ 43 | I I | I {prev}--I-----+ 44 | I I +---I---{next} I 45 | I I I . . . I 46 | +==============+ +===========+ 47 | @endcode 48 | The next and prev pointer of an empty @ref cring_t item points to itself. 49 | */ 50 | #ifdef _MSC_VER 51 | #define __typeof__ __typeof 52 | #endif 53 | 54 | typedef struct cring_t cring_t; 55 | 56 | /** Base ring structure. */ 57 | struct cring_t 58 | { 59 | cring_t * next; /**< pointer to the next ring element. */ 60 | cring_t * prev; /**< pointer to the next ring element. */ 61 | }; 62 | 63 | #ifndef offsetof 64 | /** @def offsetof(TYPE, MEMBER) 65 | Return the offset of given member from the begining of the given 66 | structure type. 67 | @param TYPE Structure type. 68 | @param MEMBER Structure member name. 69 | 70 | Example: 71 | @code 72 | struct Base { 73 | int n1; 74 | int n2; 75 | . . . 76 | }; 77 | int ofs = 78 | @endcode 79 | In this example offsetof(Base,n2) is equal to 4 (sizeof(int)) 80 | */ 81 | #define offsetof(TYPE, MEMBER) (unsigned int) &((TYPE *) 0)->MEMBER 82 | #endif 83 | 84 | /** Cast the pointer to the member of structure to the pointer 85 | to the base structure. 86 | * @param TYPE Base structure type. 87 | * @param MEMBER Member of the base structure. 88 | * @param PTR Pointer to this member. 89 | * @return Pointer to the base structure. 90 | * 91 | * Example: 92 | * The base structure looks like: 93 | * @code 94 | * struct Base { 95 | * cring_t ring1; 96 | * cring_t ring2; 97 | * . . . 98 | * }; 99 | * @endcode 100 | * We need to organize this type objects to two independent rings. 101 | * @code 102 | * static cring_t r1; 103 | * static cring_t r2; 104 | * @endcode 105 | * We will use @a ring1 member for work with the first ring and @a ring2 106 | * for the second one. 107 | * To take the first item in @c r1 we need just cast @c r1.next to the 108 | * (Base *) type or use the special macro. 109 | * @code 110 | * struct Base * ptr = cring_next_cast(&r1, struct Base); 111 | * @endcode 112 | * But we will make the same operations for the second ring, we will got 113 | * a pointer to the @a ring2 member of Base of the first ring item. 114 | * To cast it to the @a Base type we need for @a cring_cast. 115 | * @code 116 | * struct cring_t * r = cring_next(&r2); 117 | * struct Base * ptr = cring_cast(struct Base, ring2, r); 118 | * @endcode 119 | */ 120 | #define cring_cast(TYPE,MEMBER,PTR) ( (TYPE*) ((char*)(PTR) - offsetof(TYPE,MEMBER))) 121 | 122 | /** Return next ring item. 123 | * @param x Pointer could been converted to the @ref cring_t structure. 124 | * @return Next ring item automaticaly converted to the type of x. */ 125 | #define cring_next(x) ((__typeof__(x))(((cring_t*)(x))->next)) 126 | 127 | /** Return previous ring item. 128 | * @param x Pointer could been converted to the @ref cring_t structure. 129 | * @return Previous ring item automaticaly converted to the type of x. */ 130 | #define cring_prev(x) ((__typeof__(x))(((cring_t*)(x))->prev)) 131 | 132 | /** Return next ring item with cast conversion. 133 | * @param x Pointer could been converted to the @ref cring_t structure. 134 | * @param t Type to cast to. 135 | * @return Next ring item converted to the given type. */ 136 | #define cring_next_cast(x,t) ((t*)((cring_t*)(x))->next) 137 | 138 | /** Return next ring item with cast conversion. 139 | * @param x Pointer could been converted to the @ref cring_t structure. 140 | * @param t Type to cast to. 141 | * @return Previous ring item converted to the given type. */ 142 | #define cring_prev_cast(x,t) ((t*)((cring_t*)(x))->prev) 143 | 144 | /** Return first ring item with cast conversion 145 | * @param x Root ring item. 146 | * @param t Type to cast to. 147 | * @return The first item of the ring converted to the given type. */ 148 | #define cring_first_cast(x,t) cring_next_cast(&x,t) 149 | 150 | /** Return last ring item with cast conversion 151 | * @param x Root ring item. 152 | * @param t Type to cast to. 153 | * @return The last item of the ring converted to the given type. */ 154 | #define cring_last_cast(x,t) cring_prev_cast(&x,t) 155 | 156 | void _cring_init ( cring_t * const r ); 157 | #define cring_init(R) _cring_init((cring_t*)(R)) 158 | cring_t * _cring_erase ( cring_t * const r ); 159 | #define cring_erase(R) _cring_erase((cring_t*)(R)) 160 | cring_t * _cring_insert_after(cring_t * const r, cring_t * const i); 161 | #define cring_insert_after(R,I) _cring_insert_after((cring_t*)(R), (cring_t*)(I)) 162 | cring_t * _cring_insert_before(cring_t * const r, cring_t * const i); 163 | #define cring_insert_before(R,I) _cring_insert_before((cring_t*)(R), (cring_t*)(I)) 164 | #define cring_enqueue(R,I) cring_insert_before(R,I) 165 | cring_t * _cring_insert_ring_after(cring_t * const r, cring_t * const i); 166 | #define cring_insert_ring_after(R,I) _cring_insert_ring_after((cring_t*)(R), (cring_t*)(I)) 167 | cring_t * _cring_insert_ring_before(cring_t * const r, cring_t * const i); 168 | #define cring_insert_ring_before(R,I) _cring_insert_ring_before((cring_t*)(R), (cring_t*)(I)) 169 | cring_t * _cring_erase_ring(cring_t * const from, cring_t * const to); 170 | #define cring_erase_ring(F,T) _cring_erase_ring((cring_t*)(F), (cring_t*)(T)) 171 | int cring_is_empty(cring_t * const r); 172 | 173 | void cring_cleanup(cring_t * const r, void * const fn_destructor); 174 | 175 | typedef int cring_compare_fn(void * const p1, void * const p2); 176 | cring_t * _cring_insert_sorted(cring_t * const r, cring_t * const i, cring_compare_fn * const fn_compare); 177 | cring_t * _cring_find_sorted(cring_t * const r, cring_t * const n, cring_compare_fn * const fn_compare); 178 | #define cring_insert_sorted(R,I,C) _cring_insert_sorted((cring_t*)(R), (cring_t*)(I), (cring_compare_fn *)(C)) 179 | #define cring_find_sorted(R,I,C) _cring_find_sorted((cring_t*)(R), (cring_t*)(I), (cring_compare_fn *)(C)) 180 | 181 | cring_t * cring_zerase( cring_t * * const root, cring_t * const r ); 182 | cring_t * cring_zerase_ring( cring_t * * const root, cring_t * const from, cring_t * const to); 183 | cring_t * cring_zinsert_after (cring_t * * const root, cring_t * const i); 184 | cring_t * cring_zinsert_before(cring_t * * const root, cring_t * const i); 185 | void cring_zcleunup( cring_t * * const root, void * const fn_destructor); 186 | 187 | 188 | 189 | #define XRING_PREALLOC 16 190 | 191 | typedef struct xcring_t 192 | { 193 | struct xcring_t * next; 194 | struct xcring_t * prev; 195 | void * data; 196 | } xcring_t; 197 | 198 | xcring_t * xcring_new (void * const data); 199 | void xcring_free(xcring_t * const r, void * const fn_destructor); 200 | void xcring_cleanup(cring_t * const root, void * const fn_destructor); 201 | #define xcring_data(TYPE,R) ( (TYPE*) ((xcring_t*)R)->data ) 202 | 203 | xcring_t * xcring_enqueue(cring_t * const root, void * const data); 204 | void * xcring_dequeue(cring_t * const root); 205 | void * xcring_find (cring_t * const root, void * const pattern, 206 | int(*comparator)(const void * const pattern, 207 | const void * const data)); 208 | 209 | /** @} */ 210 | 211 | #endif 212 | -------------------------------------------------------------------------------- /cshared/cserialize.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | ###################################################################### 3 | ## 4 | ## Created by: Denis Filatov 5 | ## 6 | ## Copyleft (c) 2003 - 2015 7 | ## This code is provided under the CeCill-C license agreement. 8 | ###################################################################### 9 | *********************************************************************/ 10 | 11 | #include "cserialize.h" 12 | #include "cstr.h" 13 | #include "e4c_lite.h" 14 | #include 15 | #include 16 | 17 | #ifdef __GNUC__ 18 | #define cint_cpy(D,N,S) __builtin_memcpy((char*)(D),N,S) 19 | #else 20 | #define cint_cpy(D,N,S) memcpy((char*)(D),N,S) 21 | static const uint64_t __one64 = 1; 22 | #if !defined (_MSC_VER) 23 | uint64_t cint64_swap(uint64_t); 24 | uint32_t cint32_swap(uint32_t); 25 | uint16_t cint16_swap(uint16_t); 26 | #endif 27 | #endif 28 | 29 | #define C_ERROR(E) \ 30 | if (perror) *perror = E; \ 31 | throw(RuntimeException, E, NULL) 32 | 33 | int _cint64_write(const uint64_t value, char** const ptr, const char* const end, int * const perror) 34 | { 35 | register unsigned char* p = (unsigned char*)*ptr; 36 | if (p + 8 > (unsigned char*)end){ 37 | C_ERROR(ENOSPC); 38 | return -1; 39 | } 40 | if (0 == (((intptr_t)p) & 0x7)){ 41 | *((uint64_t*)p) = cint64_hton(value); 42 | p+=8; 43 | }else{ 44 | int i; 45 | for(i=7; i>=0; i--){ 46 | *p++ = (value>>(8*i))&0xFF; 47 | } 48 | } 49 | *ptr = (char*)p; 50 | if (perror) *perror = 0; 51 | return 0; 52 | } 53 | 54 | int _cint32_write(const uint32_t value, char** const ptr, const char* const end, int * const perror) 55 | { 56 | register unsigned char* p = (unsigned char*)*ptr; 57 | if(p + 4 > (unsigned char*)end){ 58 | C_ERROR(ENOSPC); 59 | return -1; 60 | } 61 | if (0 == (((intptr_t)p) & 0x3)){ 62 | *((uint32_t*)p) = cint32_hton(value); 63 | p+=4; 64 | }else{ 65 | int i; 66 | for(i=3; i>=0; i--){ 67 | *p++ = (value>>(8*i))&0xFF; 68 | } 69 | } 70 | *ptr = (char*)p; 71 | if (perror) *perror = 0; 72 | return 0; 73 | } 74 | 75 | int _cint16_write(const uint16_t value, char** const ptr, const char* const end, int * const perror) 76 | { 77 | register unsigned char* p = (unsigned char*)*ptr; 78 | if (p + 2 > (unsigned char*)end){ 79 | C_ERROR(ENOSPC); 80 | return -1; 81 | } 82 | *p++ = (value >> 8) & 0xFF; 83 | *p++ = value&0xFF; 84 | *ptr = (char*)p; 85 | if (perror) *perror = 0; 86 | return 0; 87 | } 88 | 89 | int _cint8_write(const uint8_t value, char** const ptr, const char* const end, int * const perror) 90 | { 91 | if (*ptr >= end) { 92 | C_ERROR(ENOSPC); 93 | return -1; 94 | } 95 | if (perror) *perror = 0; 96 | *((uint8_t*)*ptr) = value; 97 | (*ptr) ++; 98 | return 0; 99 | } 100 | 101 | uint64_t cint64_read(const char** const ptr, const char* const end, int * const perror) 102 | { 103 | uint64_t value; 104 | register const uint8_t * p = (const uint8_t *)*ptr; 105 | if (p + 8 > (const uint8_t *)end) { 106 | C_ERROR(EFAULT); 107 | return (unsigned)-1; 108 | } 109 | if (0 == (((intptr_t)p) & 0x7)){ 110 | value = *(uint64_t*)p; 111 | value = cint64_hton(value); 112 | *ptr = (char*)(p+8); 113 | }else{ 114 | int i; 115 | value=0; 116 | for(i=0; i<8; i++){ 117 | value = (value<<8) | *(p++); 118 | } 119 | *ptr = (char*)p; 120 | } 121 | if (perror) *perror = 0; 122 | return value; 123 | } 124 | 125 | uint32_t cint32_read(const char** const ptr, const char* const end, int * const perror) 126 | { 127 | uint32_t value; 128 | register const uint8_t * p = (const uint8_t*)*ptr; 129 | if(p + 4 > (const uint8_t *)end) { 130 | C_ERROR(EFAULT); 131 | return (unsigned)-1; 132 | } 133 | if (perror) *perror = 0; 134 | value = ((uint32_t)p[0]) << 24 | ((uint32_t)p[1]) << 16 | ((uint32_t)p[2]) << 8 | p[3]; 135 | *ptr = (char*)(p+4); 136 | return value; 137 | } 138 | 139 | uint16_t cint16_read(const char** const ptr, const char* const end, int * const perror) 140 | { 141 | uint32_t value; 142 | register const uint8_t * p = (const uint8_t*)*ptr; 143 | if (p + 2 > (const uint8_t *)end) { 144 | C_ERROR(EFAULT); 145 | return (uint16_t)-1; 146 | } 147 | if (perror) *perror = 0; 148 | value = ((uint16_t)p[0]) << 8 | p[1]; 149 | *ptr = (const char*)(p+2); 150 | return value; 151 | } 152 | 153 | uint8_t cint8_read(const char** const ptr, const char* const end, int * const perror) 154 | { 155 | if (*ptr >= end) { 156 | C_ERROR(EFAULT); 157 | return (uint8_t)-1; 158 | } 159 | if (perror) *perror = 0; 160 | return *(const uint8_t*)((*ptr)++); 161 | } 162 | 163 | int cintx_bytecount(uint64_t value) 164 | { 165 | int num_bytes = 0; 166 | #ifdef __GNUC__ 167 | if(value){ 168 | num_bytes = (64 + 6 - __builtin_clzll(value))/7; 169 | }else{ 170 | num_bytes = 1; 171 | } 172 | #else 173 | uint64_t overflow = 0; 174 | while(value >= overflow){ 175 | num_bytes++; 176 | overflow = __one64 << (7*num_bytes); 177 | } 178 | #endif 179 | return num_bytes; 180 | } 181 | 182 | int _cintx_write (const uint64_t value, char ** const ptr, const char * const end, int * const perror) 183 | { 184 | int num_bytes = 0; 185 | uint8_t c; 186 | uint8_t *out = (uint8_t*)(*ptr); 187 | num_bytes = cintx_bytecount(value); 188 | if(num_bytes > 8 || out+num_bytes > ((const uint8_t*)end)){ 189 | C_ERROR(ENOSPC); 190 | return (unsigned)-1; 191 | } 192 | num_bytes--; 193 | c = ~((1<<(8-num_bytes))-1); 194 | c |= (value >> (num_bytes*8)) & 0xFF; 195 | *out++ = c; 196 | while(num_bytes){ 197 | num_bytes--; 198 | c = (value >> (num_bytes*8)) & 0xFF; 199 | *out++ = c; 200 | } 201 | *ptr = (char*)out; 202 | if (perror) *perror = 0; 203 | return 0; 204 | } 205 | 206 | static int countof1(int c) 207 | { 208 | int r = 0; 209 | while(c & 0x80){ 210 | #if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 407) && !defined(__INTEL_COMPILER) 211 | return 1 + __builtin_clrsb(c<<24); 212 | #else 213 | r++; 214 | c<<=1; 215 | #endif 216 | } 217 | return r; 218 | } 219 | 220 | uint64_t cintx_read(const char** const ptr, const char* const end, int * const perror) 221 | { 222 | uint8_t c; 223 | const uint8_t* in; 224 | int i, lead_ones; 225 | in = (const uint8_t*)*ptr; 226 | if(in <= (const uint8_t*)end){ 227 | c = *in; 228 | lead_ones = countof1(c); 229 | if(in + 1 + lead_ones <= (const uint8_t*)end) { 230 | uint64_t value; 231 | value = c & ((1<<(7-lead_ones))-1); 232 | for(i=1; i<=lead_ones; i++){ 233 | value = (value<<8) | in[i]; 234 | } 235 | *ptr = (const char*)(in + 1 + lead_ones); 236 | if (perror) *perror = 0; 237 | return value; 238 | } 239 | } 240 | C_ERROR(EFAULT); 241 | return (unsigned)-1; 242 | } 243 | 244 | uint32_t cxsize_read(const char ** const ptr, const char * const end, int * const perror) 245 | { 246 | uint32_t len = (uint32_t)cintx_read(ptr, end, perror); 247 | if (perror == 0){ 248 | if (*ptr + len > end){ 249 | C_ERROR(EFAULT); 250 | return (unsigned)-1; 251 | } 252 | } 253 | if (perror) *perror = 0; 254 | return len; 255 | } 256 | 257 | int cbuf_write(const void * const p, int length, char ** const ptr, const char * const end, int * const perror) 258 | { 259 | if((*ptr) + length > end) { 260 | C_ERROR(ENOSPC); 261 | return (unsigned)-1; 262 | } 263 | cint_cpy(*ptr, p, length); 264 | *ptr = (*ptr) + length; 265 | if (perror) *perror = 0; 266 | return 0; 267 | } 268 | 269 | int cbuf_read (void * const p, int length, const char ** const ptr, const char * const end, int * const perror) 270 | { 271 | if((*ptr) + length > end) { 272 | C_ERROR(EFAULT); 273 | return -1; 274 | } 275 | if (p){ 276 | cint_cpy(p, *ptr, length); 277 | } 278 | *ptr = (*ptr) + length; 279 | if (perror) *perror = 0; 280 | return 0; 281 | } 282 | 283 | int cstr_write(const char * const p, char ** const ptr, const char * const end, int * const perror) 284 | { 285 | int ret; 286 | int len = cstrlen(p); 287 | // write size 288 | ret = cintx_write(len, ptr, end, perror); 289 | if (ret == 0 && len > 0 ) { 290 | ret = cbuf_write(p, len, ptr, end, perror); 291 | } 292 | return ret; 293 | } 294 | 295 | int cstrn_write(const char * const p, int length, char ** const ptr, const char * const end, int * const perror) 296 | { 297 | int ret; 298 | int len = cstrnlen(p, length); 299 | // write size 300 | ret = cintx_write(len, ptr, end, perror); 301 | if (ret == 0 && len > 0) { 302 | ret = cbuf_write(p, len, ptr, end, perror); 303 | } 304 | return ret; 305 | } 306 | 307 | int cstr_read(char * const p, const char ** const ptr, const char * const end, int * const perror) 308 | { 309 | // read size 310 | int len = (int)cintx_read(ptr, end, perror); 311 | if (*perror == 0){ 312 | return cbuf_read(p, len, ptr, end, perror); 313 | } 314 | return -1; 315 | } 316 | 317 | int cstrn_read(char * const p, int length, const char ** const ptr, const char * const end, int * const perror) 318 | { 319 | // read size 320 | int len = (int)cintx_read(ptr, end, perror); 321 | if (len <= length){ 322 | // read buf 323 | return cbuf_read(p, len, ptr, end, perror); 324 | } 325 | C_ERROR(EFAULT); 326 | return -1; 327 | } 328 | 329 | int cbookmark_store(cbookmark * bm, char ** const ptr, const char * const end, int * const perror) 330 | { 331 | char * p = *ptr; 332 | if (bm->idx >= sizeof(bm->ptrs) / sizeof(bm->ptrs[0])){ 333 | C_ERROR(E2BIG); 334 | return -1; 335 | } 336 | if (p >= end){ 337 | C_ERROR(ENOSPC); 338 | return -1; 339 | } 340 | bm->ptrs[bm->idx] = p; 341 | bm->idx++; 342 | *ptr = p + 1; 343 | if (perror) *perror = 0; 344 | return 0; 345 | } 346 | 347 | int cbookmark_apply(cbookmark * bm, char ** const ptr, const char * const end, int * const perror) 348 | { 349 | int size, bcount; 350 | char *p, * psize; 351 | 352 | p = *ptr; 353 | if (bm->idx == 0){ 354 | C_ERROR(E2BIG); 355 | return -1; 356 | } 357 | psize = bm->ptrs[--bm->idx]; 358 | size = p - psize - 1; 359 | bcount = cintx_bytecount(size); 360 | if (bcount == 1){ 361 | *(unsigned char*)psize = size; 362 | size = 0; // return value; 363 | } 364 | else{ 365 | if (p + bcount - 1 > end){ 366 | C_ERROR(ENOSPC); 367 | return (unsigned)-1; 368 | } 369 | memmove(psize + bcount, psize + 1, p - psize - 1); 370 | *ptr = p + bcount - 1; 371 | size = cintx_write(size, &psize, psize + bcount, perror); 372 | } 373 | if (perror) *perror = 0; 374 | return size; // size is overridden to be 0 or -1 375 | } 376 | -------------------------------------------------------------------------------- /cshared/cserialize.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | ###################################################################### 3 | ## 4 | ## Created by: Denis Filatov 5 | ## 6 | ## Copyleft (c) 2003 - 2015 7 | ## This code is provided under the CeCill-C license agreement. 8 | ###################################################################### 9 | *********************************************************************/ 10 | 11 | #ifndef cint_h 12 | #define cint_h 13 | #include 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif 18 | 19 | #include "e4c_lite.h" 20 | 21 | #if defined(__GNUC__) 22 | # define cint64_swap(X) __builtin_bswap64(X) 23 | # define cint32_swap(X) __builtin_bswap32(X) 24 | # define cint16_swap(X) __builtin_bswap16(X) 25 | #elif defined (_MSC_VER) 26 | # define cint64_swap(X) _byteswap_uint64(X) 27 | # define cint32_swap(X) _byteswap_ulong (X) 28 | # define cint16_swap(X) _byteswap_ushort(X) 29 | #define __ORDER_LITTLE_ENDIAN__ 1 30 | #define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ 31 | #else 32 | uint64_t cint64_swap(const uint64_t); 33 | uint32_t cint32_swap(const uint32_t); 34 | uint16_t cint16_swap(const uint16_t); 35 | #endif 36 | #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 37 | # define cint64_hton(X) cint64_swap(X) 38 | # define cint32_hton(X) cint32_swap(X) 39 | # define cint16_hton(X) cint16_swap(X) 40 | # define cint64_lsb(X) ((uint8_t)(((uint64_t)(X))>>56)) 41 | # define cint32_lsb(X) ((uint8_t)(((uint32_t)(X))>24)) 42 | # define cint24_lsb(X) ((uint8_t)(((uint32_t)(X))>16)) 43 | # define cint64_lsb3(X) ((uint32_t)(((uint64_t)(X))>>40)) 44 | # define cint32_lsb3(X) ((uint32_t)(((uint64_t)(X))>>8)) 45 | #else 46 | # define cint64_hton(X) (X) 47 | # define cint32_hton(X) (X) 48 | # define cint16_hton(X) (X) 49 | # define cint64_lsb(X) ((uint8_t)((X)&0xFF)) 50 | # define cint32_lsb(X) ((uint8_t)((X)&0xFF)) 51 | # define cint24_lsb(X) ((uint8_t)((X)&0xFF)) 52 | # define cint64_lsb3(X) ((uint32_t)((X)&0xFFFFFF)) 53 | # define cint32_lsb3(X) ((uint32_t)((X)&0xFFFFFF)) 54 | #endif /* __BYTE_ORDER__ */ 55 | 56 | /* serialisation */ 57 | int _cint64_write(const uint64_t n, char ** const ptr, const char * const end, int * const error); 58 | int _cint32_write(const uint32_t n, char ** const ptr, const char * const end, int * const error); 59 | int _cint16_write(const uint16_t n, char ** const ptr, const char * const end, int * const error); 60 | int _cint8_write (const uint8_t n, char ** const ptr, const char * const end, int * const error); 61 | int _cintx_write (const uint64_t n, char ** const ptr, const char * const end, int * const error); 62 | 63 | #define cint64_write(N,P,S,E) _cint64_write((uint64_t)(N), P, S, E) 64 | #define cint32_write(N,P,S,E) _cint32_write((uint32_t)(N), P, S, E) 65 | #define cint16_write(N,P,S,E) _cint16_write((uint16_t)(N), P, S, E) 66 | #define cint8_write(N,P,S,E) _cint8_write ((uint8_t)(N), P, S, E) 67 | #define cintx_write(N,P,S,E) _cintx_write ((uint32_t)(N), P, S, E) 68 | 69 | uint64_t cint64_read (const char ** const ptr, const char * const end, int * const error); 70 | uint32_t cint32_read (const char ** const ptr, const char * const end, int * const error); 71 | uint16_t cint16_read (const char ** const ptr, const char * const end, int * const error); 72 | uint8_t cint8_read (const char ** const ptr, const char * const end, int * const error); 73 | uint64_t cintx_read (const char ** const ptr, const char * const end, int * const error); 74 | uint32_t cxsize_read(const char ** const ptr, const char * const end, int * const error); 75 | int cintx_bytecount(uint64_t); 76 | 77 | int cbuf_write(const void * const p, int length, char ** const ptr, const char * const end, int * const error); 78 | int cbuf_read (void * const p, int length, const char ** const ptr, const char * const end, int * const error); 79 | 80 | typedef struct { 81 | int idx; 82 | void * ptrs[6]; 83 | }cbookmark; 84 | int cbookmark_store(cbookmark * bm, char ** const ptr, const char * const end, int * const error); 85 | int cbookmark_apply(cbookmark * bm, char ** const ptr, const char * const end, int * const error); 86 | 87 | E4C_DECLARE_EXCEPTION(cexc_readbuf); 88 | E4C_DECLARE_EXCEPTION(RuntimeException); 89 | 90 | #ifdef __cplusplus 91 | } 92 | #endif 93 | 94 | #endif 95 | -------------------------------------------------------------------------------- /cshared/cshared.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | {D5918B85-FA45-4F75-9B50-C2D3E34ABA17} 34 | Win32Proj 35 | cshared 36 | 37 | 38 | 39 | StaticLibrary 40 | true 41 | v120 42 | MultiByte 43 | 44 | 45 | StaticLibrary 46 | false 47 | v120 48 | true 49 | MultiByte 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | $(SolutionDir)build\MSVC-$(Configuration)\ 63 | $(SolutionDir)build\MSVC-$(Configuration)\obj\$(ProjectName)\ 64 | 65 | 66 | $(SolutionDir)build\MSVC-$(Configuration)\ 67 | $(SolutionDir)build\MSVC-$(Configuration)\obj\$(ProjectName)\ 68 | 69 | 70 | 71 | 72 | 73 | Level3 74 | Disabled 75 | WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) 76 | 77 | 78 | Windows 79 | true 80 | 81 | 82 | 83 | 84 | Level3 85 | 86 | 87 | MaxSpeed 88 | true 89 | true 90 | WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) 91 | 92 | 93 | Windows 94 | true 95 | true 96 | true 97 | 98 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /cshared/cstr.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | ###################################################################### 3 | ## 4 | ## Created by: Denis Filatov 5 | ## 6 | ## Copyleft (c) 2003 - 2015 7 | ## This code is provided under the CeCill-C license agreement. 8 | ###################################################################### 9 | *********************************************************************/ 10 | #define _CRT_SECURE_NO_WARNINGS 11 | #include "cstr.h" 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | int cstrlen(const char * str) 19 | { 20 | return str ? strlen(str) : 0; 21 | } 22 | int cstrnlen(const char * str, int maxsize) 23 | { 24 | int len = str ? strlen(str) : 0; 25 | return len > maxsize ? maxsize : len; 26 | } 27 | 28 | char* cstrend(const char * str) 29 | { 30 | return (char*)(str ? str + strlen(str) : NULL); 31 | } 32 | 33 | int cstrequal(const char * s1, const char * s2) 34 | { 35 | return (s1 == s2) || (s1 && s2 && 0 == strcmp(s1, s2)); 36 | } 37 | 38 | char * cstrcpy(char * dst, const char * src) 39 | { 40 | if(!dst) return (char*)0; 41 | int len = 0; 42 | if(src){ 43 | len = strlen(src); 44 | if(len){ 45 | memcpy(dst, src, len); 46 | } 47 | } 48 | dst[len]=0; 49 | return dst + len; 50 | } 51 | 52 | /* copy up to maxsize characters from src to dst and return pointer to the next byte after the end */ 53 | char * cstrncpy(char * dst, int maxsize, const char * src) 54 | { 55 | if(!dst) return (char*)0; 56 | unsigned int ms = maxsize; 57 | unsigned int len = 0; 58 | if(src && ms > 0){ 59 | len = strlen(src); 60 | if (len > ms){ 61 | len = ms; 62 | } 63 | if(len){ 64 | memcpy(dst, src, len); 65 | } 66 | } 67 | dst[len]=0; 68 | return dst + len; 69 | } 70 | 71 | /* copy up to maxsize characters from src to dst and return pointer to the next byte after the end */ 72 | char * cvstrncpy(char * dst, int maxsize, const char * ptr, ...) 73 | { 74 | va_list ap; 75 | char * p = dst; 76 | const char * r = ptr; 77 | unsigned int ms = maxsize; 78 | if(ms > 0){ 79 | va_start(ap, ptr); 80 | while(r){ 81 | unsigned int len = strlen(r); 82 | if(len > ms) len = ms; 83 | memcpy(p, r, len); 84 | p += len; 85 | ms -= len; 86 | r = va_arg(ap, const char*); 87 | } 88 | va_end(ap); 89 | *p = 0; 90 | } 91 | return p; 92 | } 93 | 94 | char * cstralloc(int size) 95 | { 96 | return (char*)malloc((size+0xF)&(~0xF)); 97 | } 98 | char * cstrdup(const char * str) 99 | { 100 | char * ret = NULL; 101 | if(str){ 102 | int len = strlen(str); 103 | if(len){ 104 | ret = cstralloc(len); 105 | memcpy(ret, str, len+1); 106 | } 107 | } 108 | return ret; 109 | } 110 | 111 | char * cstrndup(const char * str, int max_size) 112 | { 113 | char * ret = NULL; 114 | unsigned int ms = max_size; 115 | if(str){ 116 | unsigned int len = strlen(str); 117 | if(len>ms) len=ms; 118 | if(len){ 119 | ret = cstralloc(len); 120 | memcpy(ret, str, len); 121 | ret[len] = 0; 122 | } 123 | } 124 | return ret; 125 | } 126 | 127 | char * cvstrdup(const char * ptr, ...) 128 | { 129 | va_list ap; 130 | int len = 0; 131 | char *dst, *p; 132 | const char * r; 133 | 134 | if(!ptr) return (char*)ptr; 135 | 136 | // calculate size 137 | r = ptr; 138 | va_start(ap, ptr); 139 | while(r){ 140 | len += strlen(r); 141 | r = va_arg(ap, const char*); 142 | } 143 | va_end(ap); 144 | 145 | p = dst = cstralloc(len+1); 146 | if(dst){ 147 | r = ptr; 148 | va_start(ap, ptr); 149 | while(r){ 150 | len = strlen(r); 151 | memcpy(p, r, len); 152 | p += len; 153 | r = va_arg(ap, const char*); 154 | } 155 | va_end(ap); 156 | *p = 0; 157 | } 158 | return dst; 159 | } 160 | 161 | char * cstrnload(char * dst, int max_size, const pchar_t * path) 162 | { 163 | FILE * f = pchar_fopen(path, _PCH("rb")); 164 | unsigned long len, rl; 165 | unsigned long ms = max_size; 166 | if (!f) return NULL; 167 | fseek(f, 0, SEEK_END); 168 | len = ftell(f); 169 | fseek(f, 0, SEEK_SET); 170 | if (len > ms) len = ms; 171 | rl = fread(dst, 1, len, f); 172 | fclose(f); 173 | if ((int)rl < 0){ 174 | return NULL; 175 | } 176 | if (len < ms)dst[len] = 0; 177 | return dst + len; 178 | } 179 | 180 | char * cstraload(char ** p, const pchar_t * path) 181 | { 182 | char * ret = NULL; 183 | FILE * f = pchar_fopen(path, _PCH("rb")); 184 | int len; 185 | if (f){ 186 | fseek(f, 0, SEEK_END); 187 | len = ftell(f); 188 | fseek(f, 0, SEEK_SET); 189 | if (len > 0){ 190 | ret = malloc(len); 191 | if (ret){ 192 | int ms = fread(ret, 1, len, f); 193 | if (ms < len){ 194 | free(ret); 195 | *p = ret = NULL; 196 | } 197 | else{ 198 | *p = ret; 199 | ret += len; 200 | } 201 | } 202 | } 203 | fclose(f); 204 | } 205 | return ret; 206 | } 207 | 208 | const pchar_t * cstrlastpathelement(const pchar_t * str) 209 | { 210 | const pchar_t * p = pchar_rchr(str, '/'); 211 | const pchar_t * p2 = pchar_rchr(str, '/'); 212 | if(p= '0' && ch <= '9') continue; 241 | if (ch >= 'A' && ch <= 'F') continue; 242 | if (ch >= 'a' && ch <= 'f') continue; 243 | return NULL; 244 | } 245 | h = hex; 246 | while (h < e){ 247 | char ch = *h++; 248 | if (ch >= '0' && ch <= '9') ch -= '0'; 249 | else if (ch >= 'A' && ch <= 'F') ch -= 'A' - 0x0A; 250 | else if (ch >= 'a' && ch <= 'f') ch -= 'a' - 0x0A; 251 | else continue; 252 | if (!n){ 253 | *b = ch; 254 | } 255 | else{ 256 | char ch1 = *b; 257 | *b++ = (ch1 << 4) | ch; 258 | } 259 | n = !n; 260 | } 261 | if (n){ 262 | char ch1 = *b; 263 | *b++ = (ch1 << 4); 264 | n = 0; 265 | } 266 | return b; 267 | } 268 | 269 | int cstr_write(const char * const p, char ** const ptr, const char * const end, int * const error); 270 | int cstr_read(char * const p, const char ** const ptr, const char * const end, int * const error); 271 | 272 | int cstrn_write(const char * const p, int length, char ** const ptr, const char * const end, int * const error); 273 | int cstrn_read(char * const p, int length, const char ** const ptr, const char * const end, int * const error); 274 | -------------------------------------------------------------------------------- /cshared/cstr.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | ###################################################################### 3 | ## 4 | ## Created by: Denis Filatov 5 | ## 6 | ## Copyleft (c) 2003 - 2015 7 | ## This code is provided under the CeCill-C license agreement. 8 | ###################################################################### 9 | *********************************************************************/ 10 | #ifndef CSTR_H 11 | #define CSTR_H 12 | #include 13 | #include 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | int cstrlen(const char * str); 19 | int cstrnlen(const char * str, int maxsize); 20 | char* cstrend(const char * str); 21 | /* copy src to dst and return pointer to the next byte after the end */ 22 | char * cstrcpy(char * dst, const char * src); 23 | 24 | /* copy up to maxsize characters from src to dst and return pointer to the next byte after the end */ 25 | char * cstrncpy(char * dst, int maxsize, const char * src); 26 | 27 | /* copy up to maxsize characters from parameters to dst and return pointer to the next byte after the end */ 28 | char * cvstrncpy(char * dst, int maxsize, const char * ptr, ...); 29 | 30 | int cstrequal(const char * s1, const char * s2); 31 | 32 | /* allocate copy of the str */ 33 | char * cstralloc(int size); 34 | char * cstrdup(const char * str); 35 | char * cstrndup(const char * str, int max_size); 36 | 37 | /* allocate new str and collect all paramaters */ 38 | char * cvstrdup(const char * ptr, ...); 39 | 40 | int cstr_write(const char * const p, char ** const ptr, const char * const end, int * const error); 41 | int cstr_read (char * const p, const char ** const ptr, const char * const end, int * const error); 42 | 43 | int cstrn_write(const char * const p, int length, char ** const ptr, const char * const end, int * const error); 44 | int cstrn_read (char * const p, int length, const char ** const ptr, const char * const end, int * const error); 45 | 46 | char * cstr_hex2bin(char * bin, int blen, const char * hex, int hlen); 47 | 48 | /* file access functions */ 49 | #ifndef PCHAR_T_DEFINED 50 | #if defined(UNICODE) && ( defined(_WIN32) || defined(_WIN64) ) 51 | #define PCHAR16BITS 52 | #include 53 | typedef wchar_t pchar_t; 54 | #define _PCH(X) L##X 55 | #else 56 | typedef char pchar_t; 57 | #define _PCH(X) X 58 | #endif 59 | #endif 60 | 61 | /* load file content to the buffer and return pointer to the next byte after the buffer */ 62 | char * cstrnload(char * dst, int max_size, const pchar_t * path); 63 | /* load file content to the new allocated buffer, assign it to p and return pointer to the next byte after the buffer */ 64 | char * cstraload(char ** p, const pchar_t * path); 65 | 66 | /* return the last element of the path */ 67 | const pchar_t * cstrlastpathelement(const pchar_t * str); 68 | pchar_t * cstrpathextension(const pchar_t * str); 69 | 70 | 71 | #ifdef PCHAR16BITS 72 | #define pchar_len(S) wcslen(S) 73 | #define pchar_ncpy(D,S,N) wcsncpy(D,S,N) 74 | #define pchar_cpy(D,S) wcscpy(D,S) 75 | #define pchar_rchr(S,C) wcsrchr(S,C) 76 | #define pchar_fopen(P,M) _wfopen(P, M) 77 | #define pchar_main(A,V) wmain(A,V) 78 | #else 79 | #define pchar_len(S) strlen(S) 80 | #define pchar_ncpy(D,S,N) strncpy(D,S,N) 81 | #define pchar_cpy(D,S) strcpy(D,S) 82 | #define pchar_rchr(S,C) strrchr(S,C) 83 | #define pchar_fopen(P,M) fopen(P, M) 84 | #define pchar_main(A,V) main(A,V) 85 | #endif 86 | #define pchar_alloc(S) ((pchar_t*)malloc(sizeof(pchar_t)*((S)+1))) 87 | 88 | #ifdef __cplusplus 89 | } 90 | #endif 91 | #endif 92 | -------------------------------------------------------------------------------- /cshared/e4c_lite.c: -------------------------------------------------------------------------------- 1 | /* 2 | * exceptions4c lightweight version 1.0 3 | * 4 | * Copyright (c) 2014 Guillermo Calvo 5 | * Licensed under the GNU Lesser General Public License 6 | * Small modification was made by Denis Filatov 7 | */ 8 | 9 | #define _CRT_SECURE_NO_WARNINGS 10 | #include 11 | #include 12 | #include 13 | #include "e4c_lite.h" 14 | 15 | E4C_DEFINE_EXCEPTION(RuntimeException, "Runtime exception.", RuntimeException); 16 | E4C_DEFINE_EXCEPTION(NullPointerException, "Null pointer.", RuntimeException); 17 | 18 | struct e4c_context e4c = {0}; 19 | static const char * err_msg[] = {"\n\nError: %s (%s)\n\n", "\n\nUncaught %s: %s\n\n thrown at %s:%d\n\n"}; 20 | 21 | #ifdef E4C_DEBUG 22 | static const char * __stages[] = { 23 | "beginning", "trying", "catching", "finalizing", "done" 24 | }; 25 | #endif 26 | static void e4c_propagate(void){ 27 | 28 | e4c.frame[e4c.frames].uncaught = 1; 29 | 30 | if(e4c.frames > 0) longjmp(e4c.jump[e4c.frames - 1], 1); 31 | 32 | if(fprintf(stderr, e4c.err.file == NULL ? err_msg[0] : err_msg[1], e4c.err.type->name, e4c.err.message, e4c.err.file, e4c.err.line) > 0) 33 | (void)fflush(stderr); 34 | 35 | exit(EXIT_FAILURE); 36 | } 37 | 38 | int e4c_try(const char * file, int line){ 39 | 40 | if(e4c.frames >= E4C_MAX_FRAMES) e4c_throw(&RuntimeException, file, line, E2BIG, "Too many `try` blocks nested."); 41 | 42 | e4c.frames++; 43 | e4c.frame[e4c.frames].stage = e4c_beginning; 44 | e4c.frame[e4c.frames].uncaught = 0; 45 | 46 | e4c.err.err = 0; 47 | 48 | #ifdef E4C_DEBUG 49 | fprintf(stderr, "TRY %d [%s]: %s:%d\n", e4c.frames, __stages[e4c.frame[e4c.frames].stage], file, line); 50 | #endif 51 | return 1; 52 | } 53 | 54 | int e4c_hook(int is_catch){ 55 | 56 | int uncaught; 57 | 58 | if (is_catch){ 59 | #ifdef E4C_DEBUG 60 | fprintf(stderr, "CATCH %d [%s]:\n", e4c.frames, __stages[e4c.frame[e4c.frames].stage]); 61 | #endif 62 | return !(e4c.frame[e4c.frames].uncaught = 0); 63 | } 64 | 65 | uncaught = e4c.frame[e4c.frames].uncaught; 66 | 67 | e4c.frame[e4c.frames].stage++; 68 | if(e4c.frame[e4c.frames].stage == e4c_catching && !uncaught) e4c.frame[e4c.frames].stage++; 69 | 70 | #ifdef E4C_DEBUG 71 | fprintf(stderr, "HOOK %d [%s]:\n", e4c.frames, __stages[e4c.frame[e4c.frames].stage]); 72 | #endif 73 | if (e4c.frame[e4c.frames].stage < e4c_done) return 1; 74 | 75 | 76 | e4c.frames--; 77 | 78 | if(uncaught) e4c_propagate(); 79 | 80 | return 0; 81 | } 82 | 83 | int e4c_extends(const struct e4c_exception_type * child, const struct e4c_exception_type * parent){ 84 | 85 | for(; child != NULL && child->supertype != child; child = child->supertype) 86 | if(child->supertype == parent) return 1; 87 | 88 | return 0; 89 | } 90 | 91 | void e4c_throw(const struct e4c_exception_type * exception_type, const char * file, int line, int err, const char * message){ 92 | 93 | e4c.err.type = (exception_type != NULL ? exception_type : &NullPointerException); 94 | e4c.err.file = file; 95 | e4c.err.line = line; 96 | e4c.err.err |= err; 97 | 98 | #ifdef E4C_DEBUG 99 | fprintf(stderr, "THROW %d [%s]:\n", e4c.frames, __stages[e4c.frame[e4c.frames].stage]); 100 | #endif 101 | (void)sprintf(e4c.err.message, "%.*s", (int)E4C_MESSAGE_SIZE - 1, (message != NULL ? message : e4c.err.type->default_message)); 102 | 103 | e4c_propagate(); 104 | } 105 | -------------------------------------------------------------------------------- /cshared/e4c_lite.h: -------------------------------------------------------------------------------- 1 | /* 2 | * exceptions4c lightweight version 1.0 3 | * 4 | * Copyright (c) 2014 Guillermo Calvo 5 | * Licensed under the GNU Lesser General Public License 6 | */ 7 | 8 | #ifndef EXCEPTIONS4C_LITE 9 | #define EXCEPTIONS4C_LITE 10 | 11 | #include 12 | #include 13 | 14 | /* Maximum number of nested `try` blocks */ 15 | #ifndef E4C_MAX_FRAMES 16 | # define E4C_MAX_FRAMES 16 17 | #endif 18 | 19 | /* Maximum length (in bytes) of an exception message */ 20 | #ifndef E4C_MESSAGE_SIZE 21 | # define E4C_MESSAGE_SIZE 128 22 | #endif 23 | 24 | /* Exception handling keywords: try/catch/finally/throw */ 25 | #ifndef E4C_NOKEYWORDS 26 | # define try E4C_TRY 27 | # define catch(type) E4C_CATCH(type) 28 | # define finally E4C_FINALLY 29 | # define throw(type, err, message) E4C_THROW(type, err, message) 30 | # define rethrow E4C_RETHROW 31 | #endif 32 | 33 | /* Represents an exception type */ 34 | struct e4c_exception_type{ 35 | const char * name; 36 | const char * default_message; 37 | const struct e4c_exception_type * supertype; 38 | }; 39 | 40 | /* Declarations and definitions of exception types */ 41 | #define E4C_DECLARE_EXCEPTION(name) extern const struct e4c_exception_type name 42 | #define E4C_DEFINE_EXCEPTION(name, default_message, supertype) const struct e4c_exception_type name = { #name, default_message, &supertype } 43 | 44 | /* Predefined exception types */ 45 | E4C_DECLARE_EXCEPTION(RuntimeException); 46 | E4C_DECLARE_EXCEPTION(NullPointerException); 47 | 48 | /* Represents an instance of an exception type */ 49 | struct e4c_exception{ 50 | char message[E4C_MESSAGE_SIZE]; 51 | int err; 52 | const char * file; 53 | int line; 54 | const struct e4c_exception_type * type; 55 | }; 56 | 57 | /* Retrieve current thrown exception */ 58 | #define E4C_EXCEPTION e4c.err 59 | 60 | /* Returns whether current exception is of a given type */ 61 | #define E4C_IS_INSTANCE_OF(t) ( e4c.err.type == &t || e4c_extends(e4c.err.type, &t) ) 62 | 63 | /* Implementation details */ 64 | #define E4C_TRY if(e4c_try(E4C_INFO) && setjmp(e4c.jump[e4c.frames - 1]) >= 0) while(e4c_hook(0)) if(e4c.frame[e4c.frames].stage == e4c_trying) 65 | #define E4C_CATCH(type) else if(e4c.frame[e4c.frames].stage == e4c_catching && E4C_IS_INSTANCE_OF(type) && e4c_hook(1)) 66 | #define E4C_FINALLY else if(e4c.frame[e4c.frames].stage == e4c_finalizing) 67 | #define E4C_THROW(type, err, message) e4c_throw(&type, E4C_INFO, err, message) 68 | #define E4C_RETHROW e4c_throw(e4c.err.type, e4c.err.file, e4c.err.line, e4c.err.err, e4c.err.message) 69 | #define FN_THROW(X) 70 | #ifndef NDEBUG 71 | # define E4C_INFO __FILE__, __LINE__ 72 | #else 73 | # define E4C_INFO NULL, 0 74 | #endif 75 | 76 | enum e4c_stage{e4c_beginning, e4c_trying, e4c_catching, e4c_finalizing, e4c_done}; 77 | extern struct e4c_context{jmp_buf jump[E4C_MAX_FRAMES]; struct e4c_exception err; struct{unsigned char stage; unsigned char uncaught;} frame[E4C_MAX_FRAMES + 1]; int frames;} e4c; 78 | extern int e4c_try(const char * file, int line); 79 | extern int e4c_hook(int is_catch); 80 | extern int e4c_extends(const struct e4c_exception_type * child, const struct e4c_exception_type * parent); 81 | extern void e4c_throw(const struct e4c_exception_type * exception_type, const char * file, int line, int err, const char * message); 82 | 83 | # endif 84 | -------------------------------------------------------------------------------- /cshared/tests/test_copts.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | ###################################################################### 3 | ## 4 | ## Created by: Denis Filatov 5 | ## 6 | ## Copyleft (c) 2003 - 2015 7 | ## This code is provided under the CeCill-C license agreement. 8 | ###################################################################### 9 | *********************************************************************/ 10 | 11 | #include "../copts.h" 12 | static const char* logfile = NULL; 13 | static int use_daemon = 1; 14 | static unsigned short port = 0; 15 | static unsigned long addr = 0; 16 | static const char* cfgfile = "not set"; 17 | 18 | static char* strs[20]; 19 | static const char * strenum[] = { 20 | "strenum0", 21 | "strenum1", 22 | "strenum2", 23 | "strenum3", 24 | "strenum4", 25 | NULL 26 | }; 27 | 28 | 29 | static int str_callback(const copt_t * opt, const char * option, copt_value_t * value) 30 | { 31 | printf("STR_CALLBACK: %s: %s\n", option, value->v_str); 32 | return 0; 33 | } 34 | static int long_callback(const copt_t * opt, const char * option, copt_value_t * value) 35 | { 36 | printf("LONG_CALLBACK: %s %ld\n", option, value->v_long); 37 | return 0; 38 | } 39 | 40 | static int short_callback(const copt_t * opt, const char * option, copt_value_t * value) 41 | { 42 | printf("SHORT_CALLBACK: %s %d\n", option, value->v_short); 43 | return 0; 44 | } 45 | 46 | static int arg_callback(const copt_t * opt, const char * option, copt_value_t * value) 47 | { 48 | printf("ARGUMENT: %s \n", value->v_str); 49 | return 0; 50 | } 51 | 52 | static copt_t options [] = { 53 | {"h?", "help", COPT_HELP, NULL , "Print this help page"}, 54 | {"C", "config", COPT_CFGFILE, &cfgfile , "Config file" }, 55 | {"b", "boolvalue", COPT_BOOL |COPT_CONFIG, NULL , "Bool test value" }, 56 | {"d", "nodaemon", COPT_BOOLI |COPT_CONFIG, &use_daemon , "Start as daemon" }, 57 | {"l", "logfile", COPT_STR |COPT_CONFIG, &logfile , "Use this log file" }, 58 | {"e", "strenum", COPT_STRENUM|COPT_CONFIG, &strenum[0] , "String enum values" }, 59 | {"pP", "port", COPT_USHORT |COPT_CONFIG, &port , "Bind to port" }, 60 | {"aA", "addr", COPT_HOST |COPT_CONFIG, &addr , "Bind to ip-address" }, 61 | {"s", "strings", COPT_STRLIST|COPT_CONFIG, &strs[0] , "String list" }, 62 | {"S", "str_cb", COPT_STR |COPT_CALLBACK,&str_callback,"String throw callback" }, 63 | {"L", "l_cb", COPT_LONG |COPT_CALLBACK,&long_callback,"Long throw callback" }, 64 | {"H", "s_cb", COPT_SHORT |COPT_CALLBACK,&short_callback,"Short throw callback" }, 65 | {NULL, NULL, COPT_CALLBACK, &arg_callback,NULL }, 66 | {NULL, NULL, COPT_END, NULL , NULL } 67 | }; 68 | 69 | int main(int argc, char** argv) 70 | { 71 | int i, j; 72 | int flags = COPT_DEFAULT|COPT_NOERR_UNKNOWN|COPT_NOAUTOHELP; 73 | 74 | i = coptions(argc, argv, flags, options); 75 | 76 | if(i<0){ 77 | if(COPT_ERC(i)){ 78 | if(i == COPT_EHELP){ 79 | coptions_help(stdout, argv[0], options, "nonarg params"); 80 | } 81 | }else{ 82 | printf("Unknown option %s\n", argv[0-i]); 83 | } 84 | } 85 | 86 | printf("help = %s\n", options[0].vptr?"yes":"no"); 87 | printf("bool = %s\n", options[1].vptr?"yes":"no"); 88 | printf("use_daemon = %s\n", use_daemon?"yes":"no"); 89 | printf("logfile = %s\n", logfile); 90 | printf("port = %d\n", port); 91 | printf("addr = %08lX\n", addr); 92 | printf("strenum=%d(%s)\n", 93 | (int)(((const char **)options[5].vptr) - &strenum[0]), 94 | *(const char **)options[5].vptr ); 95 | { 96 | char ** b = &strs[0]; 97 | char ** e = options[8].vptr; 98 | printf("strlist: count=%d\n", (int)(e - b)); 99 | while(b < e){ 100 | printf("\t%s\n", *b); 101 | b++; 102 | } 103 | } 104 | if(i>0){ 105 | printf("\nNonoptions:\n"); 106 | for(j=1; j. 17 | @license LGPL-3.0+ 18 | 19 | In particular cases this program can be distributed under other license 20 | by the simple request to the author. 21 | *********************************************************************/ 22 | 23 | #ifndef fitsec_h 24 | #define fitsec_h 25 | #ifdef WIN32 26 | #ifdef LIBFITSEC_EXPORTS 27 | #define FITSEC_EXPORT __declspec(dllexport) 28 | #else 29 | #define FITSEC_EXPORT __declspec(dllimport) 30 | #endif 31 | #else 32 | #define FITSEC_EXPORT 33 | #endif 34 | 35 | /* configuration */ 36 | #define FITSEC_HAVE_OPENSSL 37 | #define FITSEC_AID_CAM 36 38 | #define FITSEC_AID_DENM 37 39 | #define FITSEC_AID_ANY -1 40 | 41 | #include "fitsec_crypt.h" 42 | 43 | #ifdef __cplusplus 44 | extern "C" { 45 | #endif 46 | 47 | typedef struct FitSec FitSec; 48 | typedef struct FSCertificate FSCertificate; 49 | typedef int FSItsAid; 50 | 51 | typedef enum { 52 | FSFALSE, 53 | #define FSFALSE FSFALSE 54 | FSTRUE 55 | #define FSTRUE FSTRUE 56 | }FSBOOL; 57 | 58 | typedef struct FSLocation { 59 | long latitude; 60 | long longitude; 61 | unsigned short elevation; 62 | } FSLocation; 63 | 64 | typedef unsigned long long Time64; 65 | typedef unsigned long Time32; 66 | 67 | typedef enum { 68 | FS_PAYLOAD_UNSECURED, 69 | FS_PAYLOAD_SIGNED, 70 | FS_PAYLOAD_ENCRYPTED, 71 | FS_PAYLOAD_SIGNED_EXTERNAL, 72 | FS_PAYLOAD_SIGNED_AND_ENCRYPTED, 73 | } FSPayloadType; 74 | 75 | enum FSEventId { 76 | FSEvent_ChangeId = 1, 77 | }; 78 | typedef FSBOOL FitSec_Event_Fn(FitSec * e, void * user, int event, void * params); 79 | 80 | /** Configuration flags */ 81 | enum FitSecEngineFlags { 82 | /** must be set to send requests for unknown certificates */ 83 | FS_USE_CERT_REQUEST = 1, 84 | 85 | /** send requested AA certificate only if both AA and AT certificate has been requested 86 | from other side and both AA and AT digests are pointed to the currently used certificates. 87 | The idea is to sign messages by certificate chain only if both AA and AT has been requested. 88 | !This is a non-standard behavior! */ 89 | FS_SEND_AA_CERT_IF_BOTH_REQUESTED = 1, 90 | 91 | /** request both AT and AA certificates if AA certificate needs to be requested. 92 | !This is a non-standard behavior! */ 93 | FS_REQUEST_AT_CERT_WITH_AA = 2, 94 | 95 | /** do not sign next cam with certificate chain if some message signed with chain containing AA certificate was 96 | received after request */ 97 | FS_CANCEL_AA_REQUEST = 4, 98 | }; 99 | 100 | typedef struct FitSecConfig 101 | { 102 | const char * storage; // path to load and store certificates (Deprecated and not used anymore!) 103 | int hexadecimal; // certificate data is in hexadecimal form 104 | unsigned int version; // default protocol version (2) 105 | int certPeriod; // set to -1 to do not send certificates in CAM, 106 | // set to 0 to send certificates in each CAM 107 | // set to 1000 (100 msec) to send each second. 108 | unsigned int flags; // see FitSecEngineFlags 109 | const FSCryptEngineConfig * crypt; // crypto engine to be used (use openssl by default) 110 | FitSec_Event_Fn * cbOnEvent; // user callback function to be called when some event has been occured (see FSEventId) 111 | void * cbUser; // user pointer to be passed to the callback function 112 | } FitSecConfig; 113 | 114 | /** Initialize the config structure with default values */ 115 | FITSEC_EXPORT void FitSecConfig_InitDefault(FitSecConfig * cfg); 116 | 117 | /** Create and initialize engine */ 118 | FITSEC_EXPORT FitSec * FitSec_New(const FitSecConfig * config); 119 | 120 | /** Install certificate (root, AA, local AT pseudonymes) */ 121 | FITSEC_EXPORT const FSCertificate * FitSec_InstallCertificate(FitSec * e, 122 | const char * cert, int cert_length, 123 | const char * vkey, int vkey_length, 124 | const char * ekey, int ekey_length, 125 | int * perror 126 | ); 127 | 128 | /** Select certificate to be used as current pseudonym. 129 | This function will trigger the Id changing process */ 130 | FITSEC_EXPORT FSBOOL FitSec_Select(FitSec * e, unsigned int cert_id); 131 | 132 | /** Cleanup all data, forget all foreign certificates, 133 | clean all local certificates if clean_local flag is set */ 134 | FITSEC_EXPORT void FitSec_Clean(FitSec * e, int clean_local); 135 | 136 | /** Cleanup engine and free all allocated memory */ 137 | FITSEC_EXPORT void FitSec_Free(FitSec * e); 138 | 139 | /** Returns the message corresponding to the error value */ 140 | FITSEC_EXPORT const char * FitSec_ErrorMessage(int err); 141 | 142 | typedef struct { 143 | FSItsAid aid; 144 | union{ 145 | struct { 146 | unsigned char version; 147 | unsigned int flags[1]; 148 | }ssp; 149 | char data[32]; // the length of SSP is limited to 31 octet in TS103097 150 | }u; 151 | } FSItsAidSsp; 152 | 153 | typedef enum { 154 | FS_SI_SELF, 155 | FS_SI_DIGEST, 156 | FS_SI_CERTIFICATE, 157 | FS_SI_CERTIFICATE_CHAIN, 158 | FS_SI_OTHER_DIGEST, 159 | FS_SI_NO_SIGNATURE, 160 | } FSSignerInfoType; 161 | 162 | typedef struct FSMessageInfo { 163 | int status; // error value. 164 | const char * errmsg; // error description 165 | char * payload; 166 | int payloadSize; 167 | FSPayloadType payloadType; 168 | FSLocation position; 169 | Time64 generationTime; 170 | Time32 expirationTime; 171 | FSSignerInfoType si_type; 172 | const FSCertificate * cert; 173 | FSItsAidSsp ssp; 174 | 175 | // internal data 176 | void *_ptrs[8]; 177 | } FSMessageInfo; 178 | 179 | /** Sign ITS message. 180 | * @param e [In] The engine 181 | * @param m [In/Out] Message Info structure 182 | * @param buf [Out] Pointer to the buffer to store message header 183 | * @param bufsize [In] The max size of the buffer 184 | * @return message size or -1 for error 185 | * Note: All parameters must be identical for both functions. 186 | * Each call to FitSec_PrepareMessage must be followed by FitSec_SignMessage. 187 | * 188 | * Description of fields in FSMessageInfo: 189 | * | FitSec_PrepareMessage | FitSec_SignMessage 190 | * ---------------|--------------------------------------------|------------------ 191 | * payload | out: returns address to copy payload | in: the same address as returned from FitSec_PrepareMessage 192 | * payloadSize | - | in: the size of the payload. This field MUST be initialized between functions call 193 | * payloadType | in: the type of the payload | - 194 | * position | in: current position. Not needed for CAM | - 195 | * generationTime | in: the timestamp of the last GPS fix | - 196 | * expirationTime | - unsupported | - 197 | * si_type | out: signer info of the message | in: must be the same as returned from FitSec_PrepareMessage 198 | * cert | out: certificate to be used to sign message| in: the same value as returned from FitSec_PrepareMessage 199 | * ssp | in: the ssp bits representing content of | - 200 | * | the message. These bits will be used to| 201 | * | select proper certificate. | 202 | */ 203 | FITSEC_EXPORT int FitSec_PrepareMessage(FitSec * e, FSMessageInfo* m, char * buf, int bufsize); 204 | FITSEC_EXPORT int FitSec_SignMessage(FitSec * e, FSMessageInfo* m, char * buf, int bufsize); 205 | 206 | /** Verify ITS message. 207 | * @param e [In] The engine 208 | * @param info [In/Out] Message information. 209 | * @param msg [In] Pointer to the buffer of the message to be verified 210 | * @param msgize [In] The size of the buffer 211 | * @return FSTRUE for Success or FSFALSE for error. See info->status for error value 212 | * 213 | * Description of fields in FSMessageInfo: 214 | * | FitSec_Verify 215 | * ---------------|-------------------------------------------- 216 | * payload | out: points to the first byte of payload 217 | * payloadSize | out: the size of message payload 218 | * payloadType | out: the type of the payload 219 | * position | out: the remote position where message has been signed 220 | * generationTime | out: the time when message has been generated 221 | * expirationTime | - unsupported for now 222 | * si_type | out: signer info of the message 223 | * cert | out: the AT certificate that has been used to sign message 224 | * ssp | out: the AID of the message and SSP of the certificate 225 | */ 226 | FITSEC_EXPORT FSBOOL FitSec_Verify(FitSec * e, FSMessageInfo * info, const void * msg, int msgsize); 227 | 228 | #ifdef __cplusplus 229 | } 230 | #endif 231 | #endif 232 | -------------------------------------------------------------------------------- /libfitsec/fitsec_crypt.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | This file is a part of FItsSec project: Implementation of ETSI TS 103 097 3 | Copyright (C) 2015 Denis Filatov (danya.filatov()gmail.com) 4 | 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed under GNU GPLv3 in the hope that it will 11 | be useful, but WITHOUT ANY WARRANTY; without even the implied warranty 12 | of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with Fitsec. If not, see . 17 | @license LGPL-3.0+ 18 | 19 | In particular cases this program can be distributed under other license 20 | by simple request to the author. 21 | *********************************************************************/ 22 | 23 | #ifndef fitsec_crypt_h 24 | #define fitsec_crypt_h 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | typedef struct FSCryptKey FSCryptKey; 30 | typedef struct FSCryptSignature FSCryptSignature; 31 | typedef struct FSCryptHash FSCryptHash; 32 | typedef struct FSCryptEngine FSCryptEngine; 33 | typedef struct FSCryptEngineConfig FSCryptEngineConfig; 34 | 35 | typedef enum { 36 | FS_SHA256, 37 | FS_SHA224, 38 | 39 | FSCryptHashAlgorithm_Max 40 | }FSCryptHashAlgorithm; 41 | 42 | typedef enum { 43 | FS_ECDSA_NISTP256, 44 | FS_ECIES_NISTP256, 45 | 46 | FSCryptPKAlgorithm_Max 47 | }FSCryptPKAlgorithm; 48 | 49 | typedef enum { 50 | FS_AES_128_CCM 51 | }FSCryptSymmAlgorithm; 52 | 53 | typedef enum { 54 | FS_X_COORDINATE_ONLY = 0, 55 | FS_COMPRESSED_LSB_Y_0 = 2, 56 | FS_COMPRESSED_LSB_Y_1 = 3, 57 | FS_UNCOMPRESSED = 4 58 | }FitSecEccPointType; 59 | 60 | typedef struct FSCryptHashConfig { 61 | FSCryptHash* (*New) (FSCryptHashAlgorithm alg); 62 | void (*Free) (FSCryptHash * c); 63 | unsigned char * (*Calc) (FSCryptHashAlgorithm alg, unsigned char * hash, const void * ptr, int length); 64 | int (*Init) (FSCryptHash * h); 65 | void (*Update) (FSCryptHash * h, const void * ptr, int length); 66 | void (*Finalize)(FSCryptHash * h, unsigned char * hash); 67 | }FSCryptHashConfig; 68 | 69 | typedef struct FSCryptKeyConfig { 70 | FSCryptKey * (*Read) (FSCryptEngine * c, FSCryptPKAlgorithm alg, FSCryptSymmAlgorithm sym, int type, const unsigned char * x, const unsigned char * y); 71 | int (*SetPrivate)(FSCryptKey * k, const unsigned char * value, int vlength); 72 | void (*Free) (FSCryptKey * k); 73 | }FSCryptKeyConfig; 74 | 75 | typedef struct FSCryptSignatureConfig { 76 | FSCryptSignature * (*Read) (FSCryptEngine * c, const unsigned char * s, const unsigned char * rx, FitSecEccPointType type); 77 | FSCryptSignature * (*Sign) (FSCryptEngine * c, const FSCryptKey * key, const unsigned char * hash); 78 | void (*Write) (FSCryptSignature* t, unsigned char * s, unsigned char * rx, FitSecEccPointType * type); 79 | int (*Verify) (FSCryptSignature* t, const FSCryptKey * key, const unsigned char * hash); 80 | void (*Free) (FSCryptSignature* t); 81 | }FSCryptSignatureConfig; 82 | 83 | struct FSCryptEngineConfig { 84 | FSCryptEngine * (*New) (const FSCryptEngineConfig * cfg, void * param); 85 | void (*Free)(FSCryptEngine*); 86 | const FSCryptHashConfig * Hash; 87 | const FSCryptKeyConfig * Key; 88 | const FSCryptSignatureConfig * Signature; 89 | }; 90 | 91 | #ifdef FITSEC_HAVE_OPENSSL 92 | FITSEC_EXPORT const FSCryptEngineConfig * FSCryptEngineConfig_OpenSSL(); 93 | #define FSCryptEngineConfig_Default FSCryptEngineConfig_OpenSSL 94 | #endif 95 | 96 | #ifdef __cplusplus 97 | } 98 | #endif 99 | #endif 100 | -------------------------------------------------------------------------------- /libfitsec/libfitsec.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {3B631B0D-6665-43D9-825B-F562CF8048F9} 15 | Win32Proj 16 | libfitsec 17 | 18 | 19 | 20 | DynamicLibrary 21 | true 22 | v120 23 | MultiByte 24 | 25 | 26 | DynamicLibrary 27 | false 28 | v120 29 | true 30 | MultiByte 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | true 44 | $(SolutionDir)build\MSVC-$(Configuration)\ 45 | $(SolutionDir)build\MSVC-$(Configuration)\obj\$(ProjectName)\ 46 | 47 | 48 | false 49 | $(SolutionDir)build\MSVC-$(Configuration)\ 50 | $(SolutionDir)build\MSVC-$(Configuration)\obj\$(ProjectName)\ 51 | 52 | 53 | 54 | 55 | 56 | Level3 57 | Disabled 58 | WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBFITSEC_EXPORTS;%(PreprocessorDefinitions) 59 | $(SolutionDir)\cshared;C:\OpenSSL\Win32\include 60 | 61 | 62 | Windows 63 | true 64 | libeay32MDd.lib;ssleay32MDd.lib;%(AdditionalDependencies) 65 | C:\OpenSSL\Win32\lib\VC\static 66 | 67 | 68 | 69 | 70 | Level3 71 | 72 | 73 | MaxSpeed 74 | true 75 | true 76 | WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBFITSEC_EXPORTS;%(PreprocessorDefinitions) 77 | $(SolutionDir)\cshared;C:\OpenSSL\Win32\include 78 | 79 | 80 | Windows 81 | true 82 | true 83 | true 84 | libeay32MDd.lib;ssleay32MDd.lib;%(AdditionalDependencies) 85 | C:\OpenSSL\Win32\lib\VC\static 86 | 87 | 88 | 89 | 90 | {d5918b85-fa45-4f75-9b50-c2d3e34aba17} 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /libfitsec/plugins/fitsec_openssl.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | This file is a part of FItsSec project: Implementation of ETSI TS 103 097 3 | Copyright (C) 2015 Denis Filatov (danya.filatov()gmail.com) 4 | 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed under GNU GPLv3 in the hope that it will 11 | be useful, but WITHOUT ANY WARRANTY; without even the implied warranty 12 | of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with Fitsec. If not, see . 17 | @license LGPL-3.0+ 18 | 19 | In particular cases this program can be distributed under other license 20 | by simple request to the author. 21 | *********************************************************************/ 22 | 23 | #include 24 | //#include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include "../fitsec_crypt.h" 31 | #include 32 | 33 | #if defined(WIN32) && !defined(FITSEC_EXPORT) 34 | #ifdef LIBFITSEC_EXPORTS 35 | #define FITSEC_EXPORT __declspec(dllexport) 36 | #else 37 | #define FITSEC_EXPORT __declspec(dllimport) 38 | #endif 39 | #else 40 | #define FITSEC_EXPORT 41 | #endif 42 | 43 | 44 | static FSCryptEngine * OpenSSL_New (const FSCryptEngineConfig * cfg, void * param); 45 | static void OpenSSL_Free(FSCryptEngine*); 46 | 47 | static FSCryptHash * OpenSSL_HashNew(FSCryptHashAlgorithm alg); 48 | static void OpenSSL_HashFree(FSCryptHash * c); 49 | static unsigned char * OpenSSL_HashCalc(FSCryptHashAlgorithm alg, unsigned char * hash, const void * ptr, int length); 50 | static int OpenSSL_HashInit(FSCryptHash * h); 51 | static void OpenSSL_HashUpdate(FSCryptHash * h, const void * ptr, int length); 52 | static void OpenSSL_HashFinalize(FSCryptHash * h, unsigned char * hash); 53 | 54 | static FSCryptKey * OpenSSL_KeyRead(FSCryptEngine * c, FSCryptPKAlgorithm alg, FSCryptSymmAlgorithm sym, int type, const unsigned char * x, const unsigned char * y); 55 | static int OpenSSL_SetPrivateKey(FSCryptKey * k, const unsigned char * value, int vlength); 56 | static void OpenSSL_KeyFree(FSCryptKey * k); 57 | 58 | static FSCryptSignature * OpenSSL_ReadSignature(FSCryptEngine * c, const unsigned char * s, const unsigned char * rx, FitSecEccPointType y); 59 | static FSCryptSignature * OpenSSL_Sign(FSCryptEngine * c, const FSCryptKey * key, const unsigned char * hash); 60 | static void OpenSSL_WriteSignature(FSCryptSignature* t, unsigned char * s, unsigned char * rx, FitSecEccPointType * y); 61 | static int OpenSSL_VerifySignature(FSCryptSignature* t, const FSCryptKey * key, const unsigned char * hash); 62 | static void OpenSSL_FreeSignature(FSCryptSignature* t); 63 | 64 | static FSCryptHashConfig _openssl_hash_config = { 65 | OpenSSL_HashNew, 66 | OpenSSL_HashFree, 67 | OpenSSL_HashCalc, 68 | OpenSSL_HashInit, 69 | OpenSSL_HashUpdate, 70 | OpenSSL_HashFinalize, 71 | }; 72 | 73 | static FSCryptKeyConfig _openssl_key_config = { 74 | OpenSSL_KeyRead, 75 | OpenSSL_SetPrivateKey, 76 | OpenSSL_KeyFree 77 | }; 78 | 79 | static FSCryptSignatureConfig _openssl_signature_config = { 80 | OpenSSL_ReadSignature, 81 | OpenSSL_Sign, 82 | OpenSSL_WriteSignature, 83 | OpenSSL_VerifySignature, 84 | OpenSSL_FreeSignature 85 | }; 86 | 87 | static FSCryptEngineConfig _openssl_cfg = { 88 | OpenSSL_New, OpenSSL_Free, 89 | &_openssl_hash_config, 90 | &_openssl_key_config, 91 | &_openssl_signature_config 92 | }; 93 | 94 | FITSEC_EXPORT const FSCryptEngineConfig * FSCryptEngineConfig_OpenSSL() 95 | { 96 | return &_openssl_cfg; 97 | } 98 | 99 | static int BN_bn2bin_a(const BIGNUM *a, unsigned char *to, size_t fsize) 100 | { 101 | size_t bcount = BN_num_bytes(a); 102 | for(; bcount < fsize; bcount++) 103 | *(to++) = 0; // add padding with zeros 104 | return BN_bn2bin(a, to); 105 | } 106 | 107 | 108 | /*************************************************************************************************/ 109 | typedef struct SHAConfig { 110 | unsigned char* (*Calc) (const unsigned char *d, size_t n, unsigned char *md); 111 | int (*Init) (SHA256_CTX *c); 112 | int (*Update)(SHA256_CTX *c, const void *data, size_t len); 113 | int (*Final) (unsigned char *md, SHA256_CTX *c); 114 | }SHAConfig; 115 | 116 | static SHAConfig _sha_cfg[FSCryptHashAlgorithm_Max] = { 117 | { 118 | SHA256, 119 | SHA256_Init, 120 | SHA256_Update, 121 | SHA256_Final 122 | }, { 123 | SHA224, 124 | SHA224_Init, 125 | SHA224_Update, 126 | SHA224_Final 127 | } 128 | }; 129 | 130 | struct FSCryptHash { 131 | const SHAConfig * cfg; 132 | SHA256_CTX ctx; 133 | }; 134 | 135 | static FSCryptHash * OpenSSL_HashNew(FSCryptHashAlgorithm alg) { 136 | FSCryptHash * h = malloc(sizeof(FSCryptHash)); 137 | h->cfg = &_sha_cfg[alg]; 138 | h->cfg->Init(&h->ctx); 139 | return h; 140 | } 141 | static void OpenSSL_HashFree(FSCryptHash * c) { 142 | free(c); 143 | } 144 | static unsigned char * OpenSSL_HashCalc(FSCryptHashAlgorithm alg, unsigned char * hash, const void * ptr, int length) { 145 | return _sha_cfg[alg].Calc(ptr, length, hash); 146 | } 147 | static int OpenSSL_HashInit(FSCryptHash * h) { 148 | return h->cfg->Init(&h->ctx); 149 | } 150 | static void OpenSSL_HashUpdate(FSCryptHash * h, const void * ptr, int length) { 151 | h->cfg->Update(&h->ctx, ptr, length); 152 | } 153 | static void OpenSSL_HashFinalize(FSCryptHash * h, unsigned char * hash) { 154 | SHA256_CTX c; 155 | memcpy(&c, &h->ctx, sizeof(SHA256_CTX)); 156 | h->cfg->Final(hash, &c); 157 | } 158 | 159 | static int _nids[FSCryptPKAlgorithm_Max] = { 160 | NID_X9_62_prime256v1, 161 | NID_X9_62_prime256v1 162 | }; 163 | 164 | struct FSCryptEngine { 165 | int _rcntr; 166 | EC_GROUP * groups[FSCryptPKAlgorithm_Max]; 167 | }; 168 | 169 | static FSCryptEngine _engine = { 0 }; 170 | static FSCryptEngine * OpenSSL_New(const FSCryptEngineConfig * cfg, void * param) 171 | { 172 | int f = _engine._rcntr++; 173 | if (f == 0){ 174 | int i; 175 | for (i = 0; i < FSCryptPKAlgorithm_Max; i++){ 176 | _engine.groups[i] = EC_GROUP_new_by_curve_name(_nids[i]); 177 | } 178 | } 179 | return &_engine; 180 | } 181 | 182 | static void OpenSSL_Free(FSCryptEngine* e) 183 | { 184 | int f = --_engine._rcntr; 185 | if (f == 0){ 186 | int i; 187 | for (i = 0; i < FSCryptPKAlgorithm_Max; i++){ 188 | EC_GROUP_free(_engine.groups[i]); 189 | } 190 | } 191 | } 192 | 193 | static FSCryptKey * OpenSSL_KeyRead(FSCryptEngine * c, FSCryptPKAlgorithm alg, FSCryptSymmAlgorithm sym, int type, const unsigned char * x, const unsigned char * y) 194 | { 195 | EC_KEY * k; 196 | const EC_GROUP * group; 197 | EC_POINT * pnt; 198 | BIGNUM *bnx, *bny; 199 | 200 | group = c->groups[alg]; 201 | 202 | k = EC_KEY_new(); 203 | EC_KEY_set_group(k, group); 204 | 205 | pnt = EC_POINT_new(group); 206 | 207 | bnx = BN_new(); BN_bin2bn(x, 32, bnx); 208 | 209 | switch (type){ 210 | case FS_X_COORDINATE_ONLY: 211 | case FS_COMPRESSED_LSB_Y_0: 212 | case FS_COMPRESSED_LSB_Y_1: 213 | EC_POINT_set_compressed_coordinates_GFp(group, pnt, bnx, ((type & 2) ? 1 : 0), NULL); 214 | break; 215 | case FS_UNCOMPRESSED: 216 | bny = BN_new(); BN_bin2bn(y, 32, bny); 217 | EC_POINT_set_affine_coordinates_GFp(group, pnt, bnx, bny, NULL); 218 | BN_clear_free(bny); 219 | break; 220 | } 221 | BN_clear_free(bnx); 222 | EC_KEY_set_public_key(k, pnt); 223 | EC_POINT_free(pnt); 224 | return (FSCryptKey*)k; 225 | } 226 | 227 | static int OpenSSL_SetPrivateKey(FSCryptKey * _k, const unsigned char * value, int vlength) 228 | { 229 | EC_KEY * k = (EC_KEY *)_k; 230 | BIGNUM * p = BN_new(); 231 | BN_bin2bn(value, vlength, p); 232 | EC_KEY_set_private_key(k, p); 233 | BN_clear_free(p); 234 | return EC_KEY_check_key(k); 235 | } 236 | 237 | static void OpenSSL_KeyFree(FSCryptKey * k) 238 | { 239 | EC_KEY_free((EC_KEY *)k); 240 | } 241 | 242 | static FSCryptSignature * OpenSSL_ReadSignature(FSCryptEngine * c, const unsigned char * s, const unsigned char * rx, FitSecEccPointType type) 243 | { 244 | // ignore type 245 | ECDSA_SIG * sg = ECDSA_SIG_new(); 246 | BN_bin2bn(s, 32, sg->s); 247 | BN_bin2bn(rx, 32, sg->r); 248 | return (FSCryptSignature*)sg; 249 | } 250 | 251 | static FSCryptSignature * OpenSSL_Sign(FSCryptEngine * c, const FSCryptKey * key, const unsigned char * hash) 252 | { 253 | return (FSCryptSignature*)ECDSA_do_sign(hash, 32, (EC_KEY*)key); 254 | } 255 | 256 | static void OpenSSL_FreeSignature(FSCryptSignature* t) 257 | { 258 | ECDSA_SIG_free((ECDSA_SIG*)t); 259 | } 260 | 261 | static void OpenSSL_WriteSignature(FSCryptSignature* t, unsigned char * s, unsigned char * rx, FitSecEccPointType * type) 262 | { 263 | ECDSA_SIG * ecdsa = (ECDSA_SIG*)t; 264 | BN_bn2bin_a(ecdsa->r, rx, 32); 265 | BN_bn2bin_a(ecdsa->s, s, 32); 266 | if (type)*type = 0; // X-only 267 | } 268 | 269 | static int OpenSSL_VerifySignature(FSCryptSignature* t, const FSCryptKey * key, const unsigned char * hash) 270 | { 271 | return ECDSA_do_verify(hash, 32, (ECDSA_SIG*)t, (EC_KEY*)key); 272 | } 273 | -------------------------------------------------------------------------------- /libfitsec/src/fitsec_certhash.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | This file is a part of FItsSec project: Implementation of ETSI TS 103 097 3 | Copyright (C) 2015 Denis Filatov (danya.filatov()gmail.com) 4 | 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed under GNU GPLv3 in the hope that it will 11 | be useful, but WITHOUT ANY WARRANTY; without even the implied warranty 12 | of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with Fitsec. If not, see . 17 | @license LGPL-3.0+ 18 | 19 | In particular cases this program can be distributed under other license 20 | by simple request to the author. 21 | *********************************************************************/ 22 | 23 | #include "fitsec_i.h" 24 | #include "khash.h" 25 | #include "cmem.h" 26 | 27 | #include 28 | #define __STDC_FORMAT_MACROS 29 | #include 30 | 31 | KHASH_MAP_INIT_INT64(certs, FSCertificate*) 32 | 33 | struct CertificateHash { 34 | khash_t(certs) h; 35 | }; 36 | 37 | CertificateHash * CertificateHash_New() { 38 | return (CertificateHash *)kh_init(certs); 39 | } 40 | 41 | void CertificateHash_Free(CertificateHash * ch) 42 | { 43 | khash_t(certs) * h = (khash_t(certs)*)ch; 44 | if (h) { 45 | // release all certificates 46 | FSCertificate * c; 47 | kh_foreach_value(h, c, Certificate_Release(c)); 48 | kh_destroy(certs, h); 49 | } 50 | } 51 | 52 | void CertificateHash_Clear(CertificateHash * ch) 53 | { 54 | khash_t(certs) * h = (khash_t(certs)*)ch; 55 | if (h) { 56 | FSCertificate * c; 57 | kh_foreach_value(h, c, Certificate_Release(c)); 58 | kh_clear(certs, h); 59 | } 60 | } 61 | 62 | void CertificateHash_Purge(CertificateHash * ch) 63 | { 64 | khash_t(certs) * h = (khash_t(certs)*)ch; 65 | if (h) { 66 | khint_t k; 67 | FSCertificate * c; 68 | for (k = kh_begin(h); k != kh_end(h); ++k) { 69 | if (!kh_exist(h, k)) continue; 70 | c = kh_val(h, k); 71 | if (0 == (c->flags & CERT_LOCAL)){ 72 | kh_del(certs, h, k); 73 | Certificate_Release(c); 74 | } 75 | } 76 | } 77 | } 78 | 79 | FSCertificate * CertificateHash_Add (CertificateHash *ch, FSCertificate *c) 80 | { 81 | khash_t(certs) * h = (khash_t(certs)*)ch; 82 | if (h) { 83 | khiter_t k; 84 | int ret; 85 | k = kh_put(certs, h, c->digest, &ret); 86 | if(ret >= 0){ 87 | if(ret > 0){ 88 | kh_value(h, k) = Certificate_Retain(c); 89 | } 90 | return kh_value(h, k); 91 | } 92 | } 93 | return NULL; 94 | } 95 | 96 | FSCertificate * CertificateHash_Delete (CertificateHash * ch, HashedId8 id8) 97 | { 98 | FSCertificate * c = NULL; 99 | khash_t(certs) * h = (khash_t(certs)*)ch; 100 | if (h) { 101 | khiter_t k; 102 | k = kh_get(certs, h, id8); 103 | if(k != kh_end(h)){ 104 | c = kh_value(h, k); 105 | kh_del(certs, h, k); 106 | } 107 | } 108 | return c; 109 | } 110 | 111 | FSCertificate * CertificateHash_Find (CertificateHash * ch, HashedId8 id8) 112 | { 113 | FSCertificate * c = NULL; 114 | khash_t(certs) * h = (khash_t(certs)*)ch; 115 | if (h) { 116 | khiter_t k; 117 | k = kh_get(certs, h, id8); 118 | if(k != kh_end(h)){ 119 | c = kh_value(h, k); 120 | } 121 | } 122 | return c; 123 | } 124 | 125 | FSBOOL CertificateHash_Relink(CertificateHash * ch, FSCertificate * c) 126 | { 127 | if (NULL == c->signer){ 128 | if (NULL == c->data) return FSFALSE; 129 | c->signer = Certificate_Retain(CertificateHash_Find(ch, c->signer_digest)); 130 | if (NULL == c->signer) return FSFALSE; 131 | } 132 | if (c->signer == c) return FSTRUE; 133 | return CertificateHash_Relink(ch, c->signer); 134 | } 135 | 136 | void CertificateHash_RelinkSigners(CertificateHash * ch) 137 | { 138 | int error; 139 | khash_t(certs) * h = (khash_t(certs)*)ch; 140 | if (h) { 141 | khint_t k; 142 | for (k = kh_begin(h); k != kh_end(h); ++k) { 143 | if (kh_exist(h, k)) { 144 | FSCertificate * c = kh_value(h, k); 145 | if (!c->signer){ 146 | khint_t j = kh_get(certs, h, c->signer_digest); 147 | if (j != kh_end(h)){ 148 | c->signer = kh_value(h, j); 149 | } 150 | else{ 151 | fprintf(stderr, "%016" PRIX64 ":\t Signer %016" PRIX64 " not found\n", c->digest, c->signer_digest); 152 | } 153 | } 154 | } 155 | } 156 | for (k = kh_begin(h); k != kh_end(h); ++k) { 157 | if (kh_exist(h, k)) { 158 | FSCertificate * c = kh_value(h, k); 159 | if (!Certificate_ValidateChain(c, &error)){ 160 | fprintf(stderr, "%016" PRIX64 ":\t Certificate Chain is not valid\n", c->digest); 161 | } 162 | } 163 | } 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /libfitsec/src/fitsec_crypt.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | This file is a part of FItsSec project: Implementation of ETSI TS 103 097 3 | Copyright (C) 2015 Denis Filatov (danya.filatov()gmail.com) 4 | 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed under GNU GPLv3 in the hope that it will 11 | be useful, but WITHOUT ANY WARRANTY; without even the implied warranty 12 | of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with Fitsec. If not, see . 17 | @license LGPL-3.0+ 18 | 19 | In particular cases this program can be distributed under other license 20 | by simple request to the author. 21 | *********************************************************************/ 22 | 23 | #include "fitsec_i.h" 24 | FSCryptEngine * FitSecCrypt_New (FitSec * e, void * param) 25 | { 26 | return e->cfg->crypt->New(e->cfg->crypt, param); 27 | } 28 | 29 | void FitSecCrypt_Free(FitSec * e, FSCryptEngine* c) 30 | { 31 | e->cfg->crypt->Free(c); 32 | } 33 | 34 | FSBOOL FitSecHash_Calc(FitSec * e, FSCryptPKAlgorithm alg, unsigned char * hash, const void * data, size_t len) 35 | { 36 | if (e->cfg->crypt->Hash->Calc) 37 | return e->cfg->crypt->Hash->Calc(alg, hash, data, len) ? FSTRUE : FSFALSE; 38 | else { 39 | FSCryptHash * h = e->cfg->crypt->Hash->New(alg); 40 | if (h){ 41 | e->cfg->crypt->Hash->Update(h, data, len); 42 | e->cfg->crypt->Hash->Finalize(h, hash); 43 | e->cfg->crypt->Hash->Free(h); 44 | return FSTRUE; 45 | } 46 | } 47 | return FSFALSE; 48 | } 49 | 50 | /* 51 | FSCryptHash * FitSecHash_New(FitSec * e, FSCryptPKAlgorithm alg) 52 | { 53 | return e->cfg->crypt->Hash->New(alg); 54 | } 55 | void FitSecHash_Free(FitSec * e, FitSecHash * h) 56 | { 57 | e->cfg->crypt->Hash->Free(h); 58 | } 59 | int FitSecHash_Init(FitSec * e, FitSecHash * h) 60 | { 61 | return e->cfg->crypt->Hash->Init(h); 62 | } 63 | void FitSecHash_Update(FitSec * e, FitSecHash * h, const void * data, size_t len) 64 | { 65 | e->cfg->crypt->Hash->Update(h, data, len); 66 | } 67 | void FitSecHash_Finalize(FitSec * e, FitSecHash * h, unsigned char * hash) 68 | { 69 | e->cfg->crypt->Hash->Finalize(h, hash); 70 | } 71 | */ -------------------------------------------------------------------------------- /libfitsec/src/fitsec_error.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | This file is a part of FItsSec project: Implementation of ETSI TS 103 097 3 | Copyright (C) 2015 Denis Filatov (danya.filatov()gmail.com) 4 | 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed under GNU GPLv3 in the hope that it will 11 | be useful, but WITHOUT ANY WARRANTY; without even the implied warranty 12 | of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with Fitsec. If not, see . 17 | @license LGPL-3.0+ 18 | 19 | In particular cases this program can be distributed under other license 20 | by simple request to the author. 21 | *********************************************************************/ 22 | 23 | #define _CRT_SECURE_NO_WARNINGS 24 | #include "fitsec_i.h" 25 | #include 26 | #include 27 | #include 28 | #include "cstr.h" 29 | 30 | static struct { 31 | int id; 32 | const char * msg; 33 | }_fitsec_msg_actions[] = { 34 | { FSERR_OK, "OK" }, 35 | { FSERR_PARSEERROR, "parsing error" }, 36 | { FSERR_NOSPACE, "buffer is full" }, 37 | { FSERR_INVALID, "invalid" }, 38 | { FSERR_UNKNOWN, "unknown" }, 39 | { FSERR_ORDER, "wrong order" } //FSERR_ORDER 40 | }; 41 | 42 | static const char * _fitsec_msg_element[] = { 43 | NULL, 44 | "version", // FSERR_VERSION 45 | "size", //FSERR_SIZE 46 | "type", // FSERR_TYPE 47 | "digest", // FSERR_DIGEST 48 | "AID", // FSERR_AID 49 | "pk algorithm", // FSERR_PK_ALGORITHM 50 | "sym algorithm", // FSERR_SYM_ALGORITHM 51 | "subject type", // FSERR_SUBJECT_TYPE 52 | "subject name", // FSERR_SUBJECT_NAME 53 | "assurance", // FSERR_ASSURANCE_LEVE 54 | "aid list", // FSERR_AID_LIST 55 | "aid ssp list", // FSERR_AID_SSP_LIST 56 | "time", // FSERR_TIME 57 | "start time", // FSERR_START_TIME 58 | "end time", // FSERR_END_TIME 59 | "publik key", // FSERR_PUBLIC_KEY 60 | "verification key", // FSERR_VERIFICATION_KEY 61 | "encryption key", // FSERR_ENCRYPTION_KEY 62 | "reconstruction value", // FSERR_RECONSTRUCTION_VALUE 63 | "other attribute", // FSERR_OTHER_ATTRIBUTE 64 | "unrec cert request", //FSERR_REQUEST_UNRECOGNIZED_CERTIFICATE 65 | "duration", // FSERR_DURATION 66 | "2dlocation", // FSERR_TWODLOCATION 67 | "3dlocation", // FSERR_THREEDLOCATION 68 | "polygon", // FSERR_POLYGON 69 | "ecc point", 70 | }; 71 | 72 | static const char * _fitsec_msg_containers[] = { 73 | /* 14 */ "", 74 | /* 15 */ "trailer", 75 | /* 16 */ "encrypted key", 76 | /* 17 */ "receipient info", 77 | /* 18 */ "encryption parameters", 78 | /* 19 */ "identified", 79 | /* 20 */ "circle", 80 | /* 21 */ "polygon", 81 | /* 22 */ "region", 82 | /* 23 */ "signer", // FSERR_SIGNER 0x004000 //1<<14 83 | /* 24 */ "headers", // FSERR_HEADERS 0x008000 //1<<15 84 | /* 25 */ "subject attributes", // FSERR_SUBJECT_ATTRIBUTE 0x010000 //1<<16 85 | /* 26 */ "validity restrictions", // FSERR_VALIDITY_RESTRICTION 0x020000 //1<<17 86 | /* 27 */ "signer info", // FSERR_SIGNER_INFO 0x040000 //1<<18 87 | /* 28 */ "signature", // FSERR_SIGNATURE 0x080000 //1<<19 88 | /* 29 */ "payload", // FSERR_PAYLOAD 0x100000 //1<<20 89 | /* 30 */ "certificate", // FSERR_CERTIFICATE 0x200000 //1<<21 90 | /* 31 */ "certificate chain" // FSERR_CHAIN 0x400000 //1<<22 91 | }; 92 | 93 | static char _err[1024]; 94 | FITSEC_EXPORT const char * FitSec_ErrorMessage(int err) 95 | { 96 | int i; 97 | char * ptr = &_err[0]; 98 | const char * end = ptr + sizeof(_err); 99 | for (i = sizeof(_fitsec_msg_containers) / sizeof(_fitsec_msg_containers[0])-1; i >= 0; i--){ 100 | if (err & (1 << (FSERR_CONTAINERS_SHIFT+i))){ 101 | ptr = cstrncpy(ptr, end - ptr, _fitsec_msg_containers[i]); 102 | ptr = cstrncpy(ptr, end - ptr, ":"); 103 | } 104 | } 105 | i = FSERR_ELEMENT(err); 106 | if (i > 0 && i < sizeof(_fitsec_msg_element) / sizeof(_fitsec_msg_element[0])){ 107 | ptr = cstrncpy(ptr, end - ptr, _fitsec_msg_element[i]); 108 | ptr = cstrncpy(ptr, end - ptr, ":"); 109 | } 110 | 111 | err = FSERR_ERROR(err); 112 | for (i = 0; i < sizeof(_fitsec_msg_actions) / sizeof(_fitsec_msg_actions[0]); i++){ 113 | if (_fitsec_msg_actions[i].id == err){ 114 | *ptr++ = ' '; 115 | ptr = cstrncpy(ptr, end - ptr, _fitsec_msg_actions[i].msg); 116 | *ptr = 0; 117 | break; 118 | } 119 | } 120 | if (i == sizeof(_fitsec_msg_actions) / sizeof(_fitsec_msg_actions[0])){ 121 | ptr += sprintf(ptr, "ERR_%d", err); 122 | } 123 | return _err; 124 | } 125 | -------------------------------------------------------------------------------- /libfitsec/src/fitsec_error.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | This file is a part of FItsSec project: Implementation of ETSI TS 103 097 3 | Copyright (C) 2015 Denis Filatov (danya.filatov()gmail.com) 4 | 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed under GNU GPLv3 in the hope that it will 11 | be useful, but WITHOUT ANY WARRANTY; without even the implied warranty 12 | of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with Fitsec. If not, see . 17 | @license LGPL-3.0+ 18 | 19 | In particular cases this program can be distributed under other license 20 | by simple request to the author. 21 | *********************************************************************/ 22 | 23 | #ifndef fitsec_error_h 24 | #define fitsec_error_h 25 | 26 | #define FSISERR(X) ((0xFF&(X))?1:0) 27 | #define FSISOK(X) ((0xFF&(X))?0:1) 28 | 29 | // events (0..256) 30 | #define FSERR_OK 0x0 31 | #define FSERR_PARSEERROR EFAULT 32 | #define FSERR_NOSPACE ENOSPC 33 | #define FSERR_INVALID EINVAL 34 | #define FSERR_UNKNOWN ENOENT 35 | #define FSERR_ORDER EBADF 36 | 37 | 38 | // elementes 39 | #define FSERR_ELEMENTS_SHIFT 8 40 | 41 | enum { 42 | FSERR_VERSION = (1 << FSERR_ELEMENTS_SHIFT), 43 | FSERR_SIZE, 44 | FSERR_TYPE, 45 | FSERR_DIGEST, 46 | FSERR_AID, 47 | FSERR_PK_ALGORITHM, 48 | FSERR_SYM_ALGORITHM, 49 | FSERR_SUBJECT_TYPE, 50 | FSERR_SUBJECT_NAME, 51 | FSERR_ASSURANCE_LEVEL, 52 | FSERR_AID_LIST, 53 | FSERR_AID_SSP_LIST, 54 | FSERR_TIME, 55 | FSERR_START_TIME, 56 | FSERR_END_TIME, 57 | FSERR_PUBLIC_KEY, 58 | FSERR_VERIFICATION_KEY, 59 | FSERR_ENCRYPTION_KEY, 60 | FSERR_RECONSTRUCTION_VALUE, 61 | FSERR_OTHER_ATTRIBUTE, 62 | FSERR_REQUEST_UNRECOGNIZED_CERTIFICATE, 63 | FSERR_DURATION, 64 | FSERR_TWODLOCATION, 65 | FSERR_THREEDLOCATION, 66 | FSERR_ECC_POINT, 67 | }; 68 | 69 | // big elements 70 | #define FSERR_TRAILER (1<<15) 71 | #define FSERR_ENCRYPTED_KEY (1<<16) 72 | #define FSERR_RECIPIENT_INFO (1<<17) 73 | #define FSERR_ENC_PARAMETERS (1<<18) 74 | #define FSERR_IDENTIFIED (1<<19) 75 | #define FSERR_CIRCLE (1<<20) 76 | #define FSERR_POLYGON (1<<21) 77 | #define FSERR_REGION (1<<22) 78 | #define FSERR_SIGNER (1<<23) 79 | #define FSERR_HEADERS (1<<24) 80 | 81 | #define FSERR_SUBJECT_ATTRIBUTE (1<<25) 82 | #define FSERR_VALIDITY_RESTRICTION (1<<26) 83 | #define FSERR_SIGNER_INFO (1<<27) 84 | #define FSERR_SIGNATURE (1<<28) 85 | #define FSERR_PAYLOAD (1<<29) 86 | #define FSERR_CERTIFICATE (1<<30) 87 | #define FSERR_CHAIN (1<<31) 88 | 89 | #define FSERR_CONTAINERS_SHIFT 14 90 | #define FSERR_ELEMENT(err) (((err)>>FSERR_ELEMENTS_SHIFT) & ((1<<(FSERR_CONTAINERS_SHIFT-FSERR_ELEMENTS_SHIFT))-1)) 91 | #define FSERR_SET_ELEMENT(E,e) (((E) & (((-1)<. 17 | @license LGPL-3.0+ 18 | 19 | In particular cases this program can be distributed under other license 20 | by simple request to the author. 21 | *********************************************************************/ 22 | 23 | #ifndef fitsec_i_h 24 | #define fitsec_i_h 25 | #include "../fitsec.h" 26 | #include "fitsec_types.h" 27 | #include "fitsec_error.h" 28 | #include "cring.h" 29 | #include "cmem.h" 30 | #include "cserialize.h" 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | #define DEFAULT_PROTOCOL_VERSION 2 37 | #define FITSEC_AID_CAM 36 38 | #define FITSEC_AID_DENM 37 39 | #define MAX_AID_COUNT 16 // maximum 16 AID/SSP items per certificate 40 | 41 | HashedId3 HashedId8toId3(HashedId8 id8); 42 | HashedId8 toHashedId8(const unsigned char * buf); 43 | HashedId3 toHashedId3(const unsigned char * buf); 44 | 45 | enum { 46 | CERT_LOADED = 1, 47 | CERT_INVALID = 2, 48 | CERT_TRUSTED = 4, 49 | CERT_LOCAL = 8, 50 | }; 51 | #define FS_CERT_IS_INVALID(C) ((C) && ((C)->flags&CERT_INVALID)) 52 | #define FS_CERT_IS_TRUSTED(C) ((C) && ((C)->flags&CERT_TRUSTED)) 53 | #define FS_CERT_IS_NEW(C) ((C) && 0 == ((C)->flags&(CERT_TRUSTED|CERT_INVALID))) 54 | 55 | /* Crypto functions */ 56 | FSCryptEngine * FitSecCrypt_New(FitSec * e, void * param); 57 | void FitSecCrypt_Free(FitSec * e, FSCryptEngine* c); 58 | 59 | typedef struct FitSecKey { 60 | FSCryptPKAlgorithm alg; 61 | FSCryptSymmAlgorithm sym; 62 | int size; 63 | FSCryptKey * key; 64 | } FitSecKey; 65 | void FN_THROW(RuntimeException) FitSecKey_Read(FitSec * e, FitSecKey * const k, const char ** const ptr, const char * const end, int * const error); 66 | void FN_THROW(RuntimeException) FitSecKey_Write(FitSec * e, const FitSecKey * const k, char ** const ptr, const char * const end, int * const error); 67 | FSBOOL FitSecKey_SetPrivateKey(FitSec * e, FitSecKey * k, const char * value, size_t vlength); 68 | void FitSecKey_Cleanup(FitSec * e, FitSecKey * const k); 69 | 70 | typedef struct FitSecSignature { 71 | FSCryptPKAlgorithm alg; 72 | int size; 73 | FSCryptSignature * signature; 74 | } FitSecSignature; 75 | 76 | void FN_THROW(RuntimeException) FitSecSignature_Read(FitSec * e, FitSecSignature * const k, const char ** const ptr, const char * const end, int * const error); 77 | void FN_THROW(RuntimeException) FitSecSignature_Write(FitSec * e, const FitSecSignature * const k, char ** const ptr, const char * const end, int * const error); 78 | void FN_THROW(RuntimeException) FitSecSignature_Cleanup(FitSec * e, FitSecSignature * const k); 79 | FSBOOL FitSecSignature_Sign(FitSec * e, FitSecSignature * const s, const FitSecKey * k, const unsigned char * hash); 80 | FSBOOL FitSecSignature_Verify(FitSec * e, FitSecSignature * const s, const FitSecKey * k, const unsigned char * hash); 81 | 82 | typedef FSCryptHash FitSecHash; 83 | FSBOOL FitSecHash_Calc(FitSec * e, FSCryptPKAlgorithm alg, unsigned char * hash, const void * data, size_t len); 84 | /* 85 | 86 | FSCryptHash * FitSecHash_New(FitSec * e, FSCryptPKAlgorithm alg); 87 | void FitSecHash_Free(FitSec * e, FitSecHash * h); 88 | int FitSecHash_Init(FitSec * e, FitSecHash * h); 89 | void FitSecHash_Update(FitSec * e, FitSecHash * h, const void * data, size_t len); 90 | void FitSecHash_Finalize(FitSec * e, FitSecHash * h, unsigned char * hash); 91 | */ 92 | struct FSCertificate { 93 | cring_t ring; // ring to be added to my_certs or unknown_certs 94 | int _rcntr; // retain/release counter 95 | 96 | FitSec * e; 97 | int flags; 98 | 99 | uint8_t hash[32]; 100 | HashedId8 digest; 101 | FSCertificate * signer; 102 | HashedId8 signer_digest; 103 | 104 | SubjectType subjectType; 105 | char subjectName[32]; 106 | 107 | uint32_t start_time; 108 | uint32_t end_time; 109 | GeographicRegion region; 110 | 111 | EccPoint recValue; 112 | SubjectAssurance assurance; 113 | int aidsspcount; 114 | FSItsAidSsp aidssp[MAX_AID_COUNT]; 115 | 116 | FitSecKey vkey; 117 | FitSecKey ekey; 118 | 119 | FitSecSignature signature; 120 | 121 | unsigned int data_size; 122 | char * data; 123 | }; 124 | FSCertificate * Certificate_New(FitSec * e); 125 | // void Certificate_Free(FSCertificate * c); 126 | void Certificate_Release(FSCertificate * c); 127 | FSCertificate* Certificate_Retain(FSCertificate * c); 128 | 129 | void FN_THROW(RuntimeException) Certificate_Read(FSCertificate * c, const char** const ptr, const char* const end, int * const perror); 130 | void FN_THROW(RuntimeException) Certificate_SetData(FSCertificate * c, const char * data, int data_size, const unsigned char * hash, int * const perror); 131 | void Certificate_SetDigest(FSCertificate * c, HashedId8 digest); 132 | FSBOOL Certificate_SetPrivateKey(FSCertificate * c, int type, const char * pkdata, int pksize); 133 | 134 | FSBOOL Certificate_Validate(FSCertificate * c, int *error); 135 | FSBOOL Certificate_ValidateChain(FSCertificate * c, int *error); 136 | 137 | FSBOOL CalculateCertificateHash(FitSec * e, FSCryptPKAlgorithm alg, const char * ptr, int size, unsigned char * hash, int * const perror); 138 | FSBOOL Certificate_IsValidForTime(const FSCertificate * c, Time64 time, int * const perror); 139 | FSBOOL Certificate_IsValidForPosition(const FSCertificate * c, const FSLocation * position, int * const perror); 140 | FSBOOL Certificate_IsValidForSSP(const FSCertificate * c, const FSItsAidSsp * ssp, int * const perror); 141 | FSBOOL Certificate_IsValidFor(const FSCertificate * c, const FSItsAidSsp * ssp, const FSLocation * position, Time64 time, int * const perror); 142 | const FSItsAidSsp * Certificate_GetAidSsp(const FSCertificate * c, FSItsAid aid); 143 | 144 | FSBOOL AIDSSP_Match(const FSItsAidSsp * mask, const FSItsAidSsp * ssp); 145 | 146 | typedef struct CertificateHash CertificateHash; 147 | CertificateHash * CertificateHash_New (); 148 | void CertificateHash_Free (CertificateHash *); 149 | void CertificateHash_Clear (CertificateHash *); 150 | void CertificateHash_Purge (CertificateHash *); 151 | FSCertificate * CertificateHash_Add (CertificateHash *, FSCertificate *); 152 | FSCertificate * CertificateHash_Delete (CertificateHash *, HashedId8); 153 | FSCertificate * CertificateHash_Find (CertificateHash *, HashedId8); 154 | FSBOOL CertificateHash_Relink (CertificateHash *, FSCertificate *); 155 | void CertificateHash_RelinkSigners(CertificateHash *); 156 | 157 | struct FitSec 158 | { 159 | const FitSecConfig * cfg; 160 | FSCryptEngine * crypt; 161 | unsigned int version; 162 | unsigned int error; 163 | CertificateHash * certs; 164 | FSCertificate * currentCert; 165 | 166 | cring_t mycerts; 167 | cring_t trusted; 168 | cring_t unknown; 169 | cring_t pool; 170 | 171 | FSCertificate * requestedCert; 172 | int newNeighbourFlag; 173 | Time64 nextCertTime; 174 | }; 175 | 176 | FSCertificate * FitSec_SelectMyCertificate(FitSec * e, const FSItsAidSsp * ssp, const FSLocation * position, Time64 time); 177 | 178 | void FN_THROW(RuntimeException) SignerInfo_Read(SignerInfo * si, const char** const ptr, const char* end, int * const p_error); 179 | void FN_THROW(RuntimeException) EccPoint_Read(EccPoint * p, const char** const ptr, const char* const end, int * const p_error); 180 | void FN_THROW(RuntimeException) GeographicRegion_Read(GeographicRegion * r, const char** const ptr, const char* const end, int * const p_error); 181 | void FN_THROW(RuntimeException) TwoDLocation_Read(TwoDLocation * l, const char** const ptr, const char* const end, int * const p_error); 182 | void FN_THROW(RuntimeException) ThreeDLocation_Write(ThreeDLocation * l, char** const ptr, const char* const end, int * const p_error); 183 | void FN_THROW(RuntimeException) ThreeDLocation_Read(ThreeDLocation * l, const char** const ptr, const char* const end, int * const p_error); 184 | HashedId3 FN_THROW(RuntimeException) HashedId3_Read(const char** const ptr, const char* const end, int * const p_error); 185 | void FN_THROW(RuntimeException) HashedId3_Write(HashedId3 id3, char** const ptr, const char* const end, int * const p_error); 186 | void FN_THROW(RuntimeException) EncryptionParameters_Read(EncryptionParameters * ep, const char** const ptr, const char* end, int * const p_error); 187 | void FN_THROW(RuntimeException) RecipientInfo_Read(RecipientInfo * ri, FSCryptSymmAlgorithm sym, const char** const ptr, const char* end, int * const p_error); 188 | void FN_THROW(RuntimeException) EciesEncryptedKey_Read(EciesEncryptedKey * k, FSCryptSymmAlgorithm sym, const char** const ptr, const char* end, int * const p_error); 189 | 190 | 191 | FSBOOL GeographicRegion_IsRegionInside(const GeographicRegion * r, const GeographicRegion * s); 192 | FSBOOL GeographicRegion_IsPointInside(const GeographicRegion * r, const TwoDLocation * l); 193 | 194 | 195 | #ifdef __cplusplus 196 | } 197 | #endif 198 | #endif -------------------------------------------------------------------------------- /libfitsec/src/fitsec_types.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | This file is a part of FItsSec project: Implementation of ETSI TS 103 097 3 | Copyright (C) 2015 Denis Filatov (danya.filatov()gmail.com) 4 | 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed under GNU GPLv3 in the hope that it will 11 | be useful, but WITHOUT ANY WARRANTY; without even the implied warranty 12 | of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with Fitsec. If not, see . 17 | @license LGPL-3.0+ 18 | 19 | In particular cases this program can be distributed under other license 20 | by simple request to the author. 21 | *********************************************************************/ 22 | 23 | #include "fitsec_i.h" 24 | #include "cserialize.h" 25 | #include "cstr.h" 26 | #include "cmem.h" 27 | #include 28 | #include 29 | 30 | static int _point_sizes[FSCryptPKAlgorithm_Max] = { 31 | 32, 32 32 | }; 33 | 34 | int FitSecPoint_Size(int alg) { 35 | return _point_sizes[alg]; 36 | } 37 | 38 | void FN_THROW(RuntimeException) FitSecKey_Read(FitSec * e, FitSecKey * const k, const char ** const ptr, const char * const end, int * const perror) 39 | { 40 | int type, alg, sym=0, psize; 41 | try{ 42 | alg = cint8_read(ptr, end, perror); 43 | psize = FitSecPoint_Size(alg); 44 | switch (alg) { 45 | case FS_ECIES_NISTP256: 46 | sym = cint8_read(ptr, end, perror); 47 | case FS_ECDSA_NISTP256: 48 | type = cint8_read(ptr, end, perror); 49 | if (end - *ptr < psize || (type == FS_UNCOMPRESSED && end - *ptr < (psize * 2))){ 50 | throw(RuntimeException, FSERR_PARSEERROR, NULL); 51 | } 52 | if (k){ 53 | k->alg = alg; 54 | k->sym = sym; 55 | k->size = 0; 56 | k->key = e->cfg->crypt->Key->Read(e->crypt, alg, sym, type, (const unsigned char*)*ptr, (const unsigned char*)((type == FS_UNCOMPRESSED) ? *ptr + psize : NULL)); 57 | } 58 | *ptr += (type == FS_UNCOMPRESSED) ? 2 * psize : psize; 59 | break; 60 | default: 61 | psize = (int)cintx_read(ptr, end, perror); 62 | if (end - *ptr < psize){ 63 | throw(RuntimeException, FSERR_PARSEERROR, NULL); 64 | } 65 | // it is enough to point to existing certificate buffer 66 | if (k){ 67 | k->alg = alg; 68 | k->sym = 0; 69 | k->size = psize; 70 | k->key = (FSCryptKey*)*ptr; 71 | } 72 | *ptr = *ptr + psize; 73 | } 74 | } 75 | catch (RuntimeException){ 76 | *perror = FSERR_PUBLIC_KEY | E4C_EXCEPTION.err; 77 | } 78 | if (*perror){ 79 | throw(RuntimeException, *perror, "Public key read error"); 80 | } 81 | } 82 | 83 | void FN_THROW(RuntimeException) FitSecKey_Write(FitSec * e, const FitSecKey * const k, char ** const ptr, const char * const end, int * const perror) 84 | { 85 | // TODO: to be implemented 86 | throw(RuntimeException, 0, "FitSecKey_Write not yet implemented"); 87 | } 88 | 89 | void FitSecKey_Cleanup(FitSec * e, FitSecKey * const k) 90 | { 91 | switch (k->alg){ 92 | case FS_ECIES_NISTP256: 93 | case FS_ECDSA_NISTP256: 94 | if (k->key){ 95 | e->cfg->crypt->Key->Free(k->key); 96 | } 97 | default: 98 | break; 99 | }; 100 | } 101 | 102 | FSBOOL FitSecKey_SetPrivateKey(FitSec * e, FitSecKey * k, const char * value, size_t vlength) 103 | { 104 | FSBOOL ret = FSFALSE; 105 | switch (k->alg){ 106 | case FS_ECIES_NISTP256: 107 | case FS_ECDSA_NISTP256: 108 | if (k->key){ 109 | ret = e->cfg->crypt->Key->SetPrivate(k->key, (const unsigned char*)value, vlength); 110 | } 111 | default: 112 | break; 113 | }; 114 | return ret; 115 | } 116 | 117 | void FN_THROW(RuntimeException) FitSecSignature_Read(FitSec * e, FitSecSignature * const k, const char ** const ptr, const char * const end, int * const perror) 118 | { 119 | int type, psize, alg; 120 | const char *r, *s; 121 | try { 122 | alg = cint8_read(ptr, end, perror); 123 | psize = FitSecPoint_Size(alg); 124 | switch (alg) { 125 | case FS_ECDSA_NISTP256: 126 | type = cint8_read(ptr, end, perror); 127 | r = *ptr; 128 | if (end - (*ptr) < psize){ 129 | throw(RuntimeException, FSERR_PARSEERROR, NULL); 130 | } 131 | *ptr = *ptr + psize; 132 | if (type == FS_UNCOMPRESSED) { // skip y 133 | if (end - (*ptr) < psize){ 134 | throw(RuntimeException, FSERR_PARSEERROR, NULL); 135 | break; 136 | } 137 | *ptr = *ptr + psize; 138 | } 139 | 140 | s = *ptr; 141 | if (end - (*ptr) < psize){ 142 | throw(RuntimeException, FSERR_PARSEERROR, NULL); 143 | break; 144 | } 145 | *ptr = *ptr + psize; 146 | if (k){ 147 | k->alg = alg; 148 | k->signature = e->cfg->crypt->Signature->Read(e->crypt, (const unsigned char*)s, (const unsigned char*)r, type); 149 | } 150 | break; 151 | default: 152 | psize = (int)cintx_read(ptr, end, perror); 153 | if (end - *ptr < psize){ 154 | throw(RuntimeException, FSERR_PARSEERROR, NULL); 155 | } 156 | else{ 157 | // it is enough to point to existing certificate buffer 158 | if (k){ 159 | k->alg = alg; 160 | k->signature = (FSCryptSignature*)*ptr; 161 | } 162 | *ptr = *ptr + psize; 163 | } 164 | }; // switch 165 | *perror = 0; 166 | } 167 | catch (RuntimeException){ 168 | *perror = E4C_EXCEPTION.err | FSERR_SIGNATURE; 169 | } 170 | if (*perror){ 171 | throw(RuntimeException, *perror, "Signature read error"); 172 | } 173 | } 174 | 175 | void FN_THROW(RuntimeException) FitSecSignature_Write(FitSec * e, const FitSecSignature * const k, char ** const ptr, const char * const end, int * const error) 176 | { 177 | int psize = FitSecPoint_Size(k->alg); 178 | FitSecEccPointType ptype; 179 | char * p = *ptr; 180 | 181 | assert(k->signature); 182 | 183 | switch (k->alg){ 184 | case FS_ECIES_NISTP256: 185 | case FS_ECDSA_NISTP256: 186 | if (end - p < 2 + psize * 2){ 187 | *error = FSERR_PARSEERROR; 188 | throw(RuntimeException, *error, NULL); 189 | } 190 | p[0] = k->alg; 191 | e->cfg->crypt->Signature->Write(k->signature, (unsigned char*)p + 2 + psize, (unsigned char*)p + 2, &ptype); 192 | p[1] = ptype; 193 | *ptr = p + 2 + psize * 2; 194 | *error = 0; 195 | break; 196 | default: 197 | cstrn_write((const char*)k->signature, k->size, ptr, end, error); 198 | break; 199 | }; 200 | } 201 | 202 | FSBOOL FitSecSignature_Sign(FitSec * e, FitSecSignature * const s, const FitSecKey * k, const unsigned char * hash) 203 | { 204 | if (s->signature){ 205 | switch (s->alg){ 206 | case FS_ECDSA_NISTP256: 207 | e->cfg->crypt->Signature->Free(s->signature); 208 | break; 209 | default: 210 | break; 211 | }; 212 | } 213 | 214 | s->alg = k->alg; 215 | switch (s->alg){ 216 | case FS_ECDSA_NISTP256: 217 | s->signature = e->cfg->crypt->Signature->Sign(e->crypt, k->key, hash); 218 | break; 219 | default: 220 | s->size = 0; 221 | s->signature = NULL; 222 | break; 223 | } 224 | return s->signature ? FSTRUE : FSFALSE; 225 | } 226 | 227 | 228 | FSBOOL FitSecSignature_Verify(FitSec * e, FitSecSignature * const s, const FitSecKey * k, const unsigned char * hash) 229 | { 230 | if (s->alg != k->alg){ 231 | return FSFALSE; 232 | } 233 | switch (s->alg){ 234 | case FS_ECDSA_NISTP256: 235 | if (s->signature == NULL || k->key == NULL){ 236 | return FSFALSE; 237 | } 238 | return e->cfg->crypt->Signature->Verify(s->signature, k->key, hash); 239 | default: 240 | break; 241 | } 242 | return FSFALSE; 243 | } 244 | 245 | void FitSecSignature_Cleanup(FitSec * e, FitSecSignature * const k) 246 | { 247 | switch (k->alg){ 248 | case FS_ECDSA_NISTP256: 249 | if (k->signature){ 250 | e->cfg->crypt->Signature->Free(k->signature); 251 | } 252 | default: 253 | break; 254 | } 255 | } 256 | 257 | void FN_THROW(RuntimeException) EccPoint_Read(EccPoint * p, const char** const ptr, const char* const end, int * const perror) 258 | { 259 | p->type = cint8_read(ptr, end, perror); 260 | cbuf_read(&p->x[0], 32, ptr, end, perror); 261 | switch (p->type){ 262 | case FS_X_COORDINATE_ONLY: 263 | case FS_COMPRESSED_LSB_Y_0: 264 | case FS_COMPRESSED_LSB_Y_1: 265 | break; 266 | case FS_UNCOMPRESSED: 267 | cbuf_read(&p->y[0], 32, ptr, end, perror); 268 | break; 269 | default: 270 | cstr_read(NULL, ptr, end, perror); // skip it 271 | } 272 | } 273 | 274 | void FN_THROW(RuntimeException) TwoDLocation_Read(TwoDLocation * l, const char** const ptr, const char* const end, int * const perror) 275 | { 276 | l->latitude = (int32_t)cint32_read(ptr, end, perror); 277 | l->longitude = (int32_t)cint32_read(ptr, end, perror); 278 | } 279 | 280 | void FN_THROW(RuntimeException) FitSecLocation_Read(FSLocation * l, const char** const ptr, const char* const end, int * const perror) 281 | { 282 | l->latitude = (int32_t)cint32_read(ptr, end, perror); 283 | l->longitude = (int32_t)cint32_read(ptr, end, perror); 284 | l->elevation = (uint16_t)cint16_read(ptr, end, perror); 285 | } 286 | 287 | void FN_THROW(RuntimeException) ThreeDLocation_Read(ThreeDLocation * l, const char** const ptr, const char* const end, int * const perror) 288 | { 289 | FitSecLocation_Read(l, ptr, end, perror); 290 | } 291 | 292 | void FN_THROW(RuntimeException) ThreeDLocation_Write(FSLocation * l, char** const ptr, const char* const end, int * const perror) 293 | { 294 | try { 295 | cint32_write(l->latitude, ptr, end, perror); 296 | cint32_write(l->longitude, ptr, end, perror); 297 | cint16_write(l->elevation, ptr, end, perror); 298 | } 299 | catch (RuntimeException){ 300 | } 301 | if (*perror){ 302 | throw(RuntimeException, FSERR_PARSEERROR, "No more space to write ThreeDLocation"); 303 | } 304 | } 305 | 306 | void FN_THROW(RuntimeException) HashedId3_Write(HashedId3 id3, char** const ptr, const char* const end, int * const p_error) 307 | { 308 | cbuf_write(&id3, 3, ptr, end, p_error); 309 | } 310 | 311 | HashedId3 FN_THROW(RuntimeException) HashedId3_Read(const char** const ptr, const char* const end, int * const p_error) 312 | { 313 | HashedId3 id = 0; 314 | const char * p = *ptr; 315 | if (end - p >= 3){ 316 | id = toHashedId3((const unsigned char*)p); 317 | *ptr = p + 3; 318 | if (p_error) *p_error = 0; 319 | return id; 320 | } 321 | if (p_error) *p_error = FSERR_PARSEERROR; 322 | throw(RuntimeException, FSERR_PARSEERROR, NULL); 323 | return 0; 324 | } 325 | 326 | void FN_THROW(RuntimeException) SignerInfo_Read(SignerInfo * si, const char** const ptr, const char* end, int * const perror) 327 | { 328 | int n; 329 | unsigned int edef = e4c.err.err; 330 | e4c.err.err |= FSERR_SIGNER_INFO | FSERR_TYPE; 331 | si->type = cint8_read(ptr, end, perror); 332 | switch (si->type){ 333 | case FS_SI_SELF: 334 | break; 335 | case FS_SI_DIGEST: 336 | e4c.err.err = edef | FSERR_SIGNER_INFO | FSERR_DIGEST; 337 | cbuf_read(&si->u.digest, 8, ptr, end, perror); 338 | break; 339 | case FS_SI_CERTIFICATE: 340 | e4c.err.err = edef | FSERR_SIGNER_INFO; 341 | si->u.data.beg = *ptr; 342 | Certificate_Read(NULL, ptr, end, perror); 343 | si->u.data.end = *ptr; 344 | break; 345 | case FS_SI_CERTIFICATE_CHAIN: 346 | case FS_SI_OTHER_DIGEST: 347 | n = (int)cintx_read(ptr, end, perror); 348 | if (*ptr + n > end){ 349 | throw(RuntimeException, FSERR_PARSEERROR, NULL); 350 | } 351 | si->u.data.beg = *ptr; 352 | si->u.data.end = *ptr = si->u.data.beg + n; 353 | break; 354 | default: 355 | throw(RuntimeException, FSERR_INVALID, "Invalid signer info type"); 356 | } 357 | e4c.err.err = edef; 358 | } 359 | 360 | void FN_THROW(RuntimeException) EncryptionParameters_Read(EncryptionParameters * ep, const char** const ptr, const char* end, int * const perror) 361 | { 362 | unsigned int edef = e4c.err.err; 363 | e4c.err.err |= FSERR_ENC_PARAMETERS | FSERR_SYM_ALGORITHM; 364 | ep->sym_alg = cint8_read(ptr, end, perror); 365 | switch (ep->sym_alg){ 366 | case FS_AES_128_CCM: 367 | e4c.err.err |= edef | FSERR_ENC_PARAMETERS; 368 | cbuf_read(&ep->u.aes128ccm.nonce, sizeof(ep->u.aes128ccm.nonce), ptr, end, perror); 369 | break; 370 | default: 371 | throw(RuntimeException, FSERR_INVALID, "Invalid Symmetric algorithm"); 372 | } 373 | e4c.err.err = edef; 374 | } 375 | 376 | void FN_THROW(RuntimeException) RecipientInfo_Read(RecipientInfo * ri, FSCryptSymmAlgorithm sym, const char** const ptr, const char* end, int * const perror) 377 | { 378 | unsigned int edef; 379 | edef = e4c.err.err |= FSERR_RECIPIENT_INFO; 380 | e4c.err.err |= FSERR_DIGEST; 381 | ri->cert_id = HashedId3_Read(ptr, end, perror); 382 | e4c.err.err = edef | FSERR_PK_ALGORITHM; 383 | ri->pk_encryption = cint8_read(ptr, end, perror); 384 | switch (ri->pk_encryption){ 385 | case FS_ECIES_NISTP256: 386 | e4c.err.err = edef | FSERR_ENCRYPTION_KEY; 387 | EciesEncryptedKey_Read(&ri->u.ecies_key, sym, ptr, end, perror); 388 | break; 389 | default: 390 | e4c.err.err = edef; 391 | cstr_read(NULL, ptr, end, perror); 392 | } 393 | e4c.err.err = edef; 394 | } 395 | 396 | void FN_THROW(RuntimeException) EciesEncryptedKey_Read(EciesEncryptedKey * k, FSCryptSymmAlgorithm sym, const char** const ptr, const char* end, int * const perror) 397 | { 398 | unsigned int edef; 399 | edef = e4c.err.err |= FSERR_ENCRYPTED_KEY; 400 | e4c.err.err |= FSERR_ECC_POINT; 401 | EccPoint_Read(&k->v, ptr, end, perror); 402 | e4c.err.err = edef | FSERR_SYM_ALGORITHM; 403 | switch (sym){ 404 | case FS_AES_128_CCM: 405 | e4c.err.err = edef; 406 | cbuf_read(k->c, 16, ptr, end, perror); 407 | default: 408 | throw(RuntimeException, FSERR_INVALID, "Invalid Symmetric algorithm"); 409 | }; 410 | e4c.err.err = edef; 411 | cbuf_read(k->t, 16, ptr, end, perror); 412 | } 413 | -------------------------------------------------------------------------------- /libfitsec/src/fitsec_types.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | This file is a part of FItsSec project: Implementation of ETSI TS 103 097 3 | Copyright (C) 2015 Denis Filatov (danya.filatov()gmail.com) 4 | 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed under GNU GPLv3 in the hope that it will 11 | be useful, but WITHOUT ANY WARRANTY; without even the implied warranty 12 | of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with Fitsec. If not, see . 17 | @license LGPL-3.0+ 18 | 19 | In particular cases this program can be distributed under other license 20 | by simple request to the author. 21 | *********************************************************************/ 22 | 23 | #ifndef fitsec_types_h 24 | #define fitsec_types_h 25 | #include "cserialize.h" 26 | 27 | typedef uint64_t HashedId8; 28 | typedef uint32_t HashedId3; 29 | 30 | typedef struct { 31 | FitSecEccPointType type; 32 | uint8_t x[32]; 33 | uint8_t y[32]; 34 | } EccPoint; 35 | 36 | typedef struct SignerInfo { 37 | FSSignerInfoType type; 38 | union { 39 | HashedId8 digest; 40 | struct { 41 | const char * beg; 42 | const char * end; 43 | }data; 44 | }u; 45 | }SignerInfo; 46 | 47 | typedef struct { 48 | FSCryptSymmAlgorithm sym_alg; 49 | union { 50 | struct { 51 | uint8_t nonce[12]; 52 | }aes128ccm; 53 | }u; 54 | } EncryptionParameters; 55 | 56 | typedef struct { 57 | FSCryptPKAlgorithm alg; 58 | FSCryptSymmAlgorithm symm_alg; 59 | EccPoint public_key; 60 | } PublicKey; 61 | 62 | typedef struct EciesEncryptedKey { 63 | EccPoint v; 64 | unsigned char c[16]; 65 | unsigned char t[16]; 66 | } EciesEncryptedKey; 67 | 68 | typedef struct RecipientInfo { 69 | HashedId8 cert_id; 70 | FSCryptPKAlgorithm pk_encryption; 71 | union { 72 | EciesEncryptedKey ecies_key; 73 | }u; 74 | }RecipientInfo; 75 | 76 | typedef struct { 77 | EccPoint r; 78 | uint8_t s[32]; 79 | } EcdsaSignature; 80 | 81 | typedef struct { 82 | FSCryptPKAlgorithm algorithm; 83 | EcdsaSignature ecdsa; 84 | } Signature; 85 | 86 | typedef struct { 87 | int32_t latitude; 88 | int32_t longitude; 89 | } TwoDLocation; 90 | 91 | typedef FSLocation ThreeDLocation; 92 | typedef struct { 93 | TwoDLocation center; 94 | uint32_t radius; 95 | } CircularRegion; 96 | 97 | typedef struct { 98 | int count; 99 | struct { 100 | TwoDLocation nw; 101 | TwoDLocation se; 102 | }r[6]; 103 | } RectangularRegion; 104 | 105 | typedef struct { 106 | int count; 107 | TwoDLocation points[12]; 108 | } PolygonalRegion; 109 | 110 | typedef enum { 111 | RDICT_ISO_3166_1, 112 | RDICT_UN_STATS, 113 | } RegionDictionary; 114 | 115 | typedef struct { 116 | RegionDictionary dictionary; 117 | uint16_t identifier; 118 | int local; 119 | } IdentifiedRegion; 120 | 121 | typedef enum { 122 | REGION_NONE, 123 | REGION_CIRCLE, 124 | REGION_RECTANGLE, 125 | REGION_POLYGON, 126 | REGION_ID, 127 | } RegionType; 128 | 129 | typedef struct { 130 | RegionType type; 131 | union { 132 | CircularRegion circular; 133 | RectangularRegion rectangular; 134 | PolygonalRegion polygonal; 135 | IdentifiedRegion identified; 136 | }u; 137 | } GeographicRegion; 138 | 139 | typedef enum { 140 | FT_GENERATION_TIME = 0, 141 | FT_GENERATION_TIME_STANDARD_DEVIATION = 1, 142 | FT_EXPIRATION = 2, 143 | FT_GENERATION_LOCATION = 3, 144 | FT_REQUEST_UNRECOGNIZED_CERTIFICATE = 4, 145 | FT_ITS_AID = 5, 146 | FT_SIGNER_INFO = 128, 147 | FT_ENCRYPTION_PARAMETERS = 129, 148 | FT_RECIPIENT_INFO = 130, 149 | } HeaderFieldType; 150 | 151 | typedef enum { 152 | FT_SIGNATURE = 1, 153 | } TrailerFieldType; 154 | 155 | typedef enum { 156 | ENROLLMENT_CREDENTIAL = 0, 157 | AUTHORIZATION_TICKET = 1, 158 | AUTHORIZATION_AUTHORITY = 2, 159 | ENROLLMENT_AUTHORITY = 3, 160 | ROOT_CA = 4, 161 | CRL_SIGNER = 5, 162 | } SubjectType; 163 | 164 | typedef enum { 165 | SA_VERIFICATION_KEY = 0, 166 | SA_ENCRYPTION_KEY = 1, 167 | SA_ASSURANCE_LEVEL = 2, 168 | SA_RECONSTRUCTION_VALUE = 3, 169 | SA_ITS_AID_LIST = 32, 170 | SA_ITS_AID_SSP_LIST = 33, 171 | } SubjectAttributeType; 172 | 173 | typedef uint8_t SubjectAssurance; 174 | 175 | typedef enum { 176 | VR_TIME_END = 0, 177 | VR_TIME_START_AND_END = 1, 178 | VR_TIME_START_AND_DURATION = 2, 179 | VR_REGION = 3, 180 | } ValidityRestrictionType; 181 | 182 | #endif 183 | -------------------------------------------------------------------------------- /libfitsec/src/fitsec_unstats.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fillabs/FITSec/9af584d21926c7ee0569c7bf51afc13e318e85d9/libfitsec/src/fitsec_unstats.h -------------------------------------------------------------------------------- /tests/Makefile: -------------------------------------------------------------------------------- 1 | ###################################################################### 2 | ## 3 | ## Created by: Denis Filatov 4 | ## 5 | ## Copyleft (c) 2015 6 | ## This code is provided under the CeCill-C license agreement. 7 | ###################################################################### 8 | PROJECTROOT = .. 9 | BUILDROOT = ../build 10 | PROJECT = fitsec_tests 11 | DEBUG = yes 12 | bins = test_engine 13 | sources := test_engine.c 14 | includes += ../libfitsec 15 | packages += openssl cshared 16 | libs = $(outdir)/libfitsec.so -lm 17 | CSHAREDDIR = ../cshared 18 | include ../common.mk 19 | -------------------------------------------------------------------------------- /tests/mkgmtime.c: -------------------------------------------------------------------------------- 1 | // Found in DeSmuME 2 | // Alexis modified it a tad bit so it would compile as C (opposed to C++) 3 | 4 | /* lib/mkgmtime.c 5 | 6 | Copyright (C) 2010 DeSmuME team 7 | 8 | This file is part of DeSmuME 9 | 10 | DeSmuME is free software; you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation; either version 2 of the License, or 13 | (at your option) any later version. 14 | 15 | DeSmuME is distributed in the hope that it will be useful, 16 | but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | GNU General Public License for more details. 19 | 20 | You should have received a copy of the GNU General Public License 21 | along with DeSmuME; if not, write to the Free Software 22 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 23 | */ 24 | 25 | //Taken from newlib 1.18.0 which is licensed under GPL 2 and modified for desmume 26 | 27 | /* 28 | * mktime.c 29 | * Original Author: G. Haley 30 | * 31 | * Converts the broken-down time, expressed as local time, in the structure 32 | * pointed to by tim_p into a calendar time value. The original values of the 33 | * tm_wday and tm_yday fields of the structure are ignored, and the original 34 | * values of the other fields have no restrictions. On successful completion 35 | * the fields of the structure are set to represent the specified calendar 36 | * time. Returns the specified calendar time. If the calendar time can not be 37 | * represented, returns the value (time_t) -1. 38 | * 39 | * Modifications: Fixed tm_isdst usage - 27 August 2008 Craig Howland. 40 | */ 41 | 42 | #ifdef _MSC_VER 43 | #define _CRT_SECURE_NO_WARNINGS 44 | #endif 45 | 46 | #include 47 | #include 48 | #include 49 | #include "mkgmtime.h" 50 | 51 | #define _SEC_IN_MINUTE 60L 52 | #define _SEC_IN_HOUR 3600L 53 | #define _SEC_IN_DAY 86400L 54 | 55 | static const int DAYS_IN_MONTH[12] = 56 | {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 57 | 58 | #define _DAYS_IN_MONTH(x) ((x == 1) ? days_in_feb : DAYS_IN_MONTH[x]) 59 | 60 | static const int _DAYS_BEFORE_MONTH[12] = 61 | {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; 62 | 63 | #define _ISLEAP(y) (((y) % 4) == 0 && (((y) % 100) != 0 || (((y)+1900) % 400) == 0)) 64 | #define _DAYS_IN_YEAR(year) (_ISLEAP(year) ? 366 : 365) 65 | 66 | static void validate_structure(struct tm *tim_p) 67 | { 68 | div_t res; 69 | int days_in_feb = 28; 70 | 71 | /* calculate time & date to account for out of range values */ 72 | if (tim_p->tm_sec < 0 || tim_p->tm_sec > 59) 73 | { 74 | res = div (tim_p->tm_sec, 60); 75 | tim_p->tm_min += res.quot; 76 | if ((tim_p->tm_sec = res.rem) < 0) 77 | { 78 | tim_p->tm_sec += 60; 79 | --tim_p->tm_min; 80 | } 81 | } 82 | 83 | if (tim_p->tm_min < 0 || tim_p->tm_min > 59) 84 | { 85 | res = div (tim_p->tm_min, 60); 86 | tim_p->tm_hour += res.quot; 87 | if ((tim_p->tm_min = res.rem) < 0) 88 | { 89 | tim_p->tm_min += 60; 90 | --tim_p->tm_hour; 91 | } 92 | } 93 | 94 | if (tim_p->tm_hour < 0 || tim_p->tm_hour > 23) 95 | { 96 | res = div (tim_p->tm_hour, 24); 97 | tim_p->tm_mday += res.quot; 98 | if ((tim_p->tm_hour = res.rem) < 0) 99 | { 100 | tim_p->tm_hour += 24; 101 | --tim_p->tm_mday; 102 | } 103 | } 104 | 105 | if (tim_p->tm_mon > 11) 106 | { 107 | res = div (tim_p->tm_mon, 12); 108 | tim_p->tm_year += res.quot; 109 | if ((tim_p->tm_mon = res.rem) < 0) 110 | { 111 | tim_p->tm_mon += 12; 112 | --tim_p->tm_year; 113 | } 114 | } 115 | 116 | if (_DAYS_IN_YEAR (tim_p->tm_year) == 366) 117 | days_in_feb = 29; 118 | 119 | if (tim_p->tm_mday <= 0) 120 | { 121 | while (tim_p->tm_mday <= 0) 122 | { 123 | if (--tim_p->tm_mon == -1) 124 | { 125 | tim_p->tm_year--; 126 | tim_p->tm_mon = 11; 127 | days_in_feb = 128 | ((_DAYS_IN_YEAR (tim_p->tm_year) == 366) ? 129 | 29 : 28); 130 | } 131 | tim_p->tm_mday += _DAYS_IN_MONTH (tim_p->tm_mon); 132 | } 133 | } 134 | else 135 | { 136 | while (tim_p->tm_mday > _DAYS_IN_MONTH (tim_p->tm_mon)) 137 | { 138 | tim_p->tm_mday -= _DAYS_IN_MONTH (tim_p->tm_mon); 139 | if (++tim_p->tm_mon == 12) 140 | { 141 | tim_p->tm_year++; 142 | tim_p->tm_mon = 0; 143 | days_in_feb = 144 | ((_DAYS_IN_YEAR (tim_p->tm_year) == 366) ? 145 | 29 : 28); 146 | } 147 | } 148 | } 149 | } 150 | 151 | 152 | static const unsigned long _leap_moments[] = { 153 | 1136073600, 154 | 1230768000, 155 | 1341100800, 156 | 1435708800, 157 | }; 158 | 159 | time_t addleapseconds(time_t t) 160 | { 161 | int i; 162 | for (i = 0; i < sizeof(_leap_moments) / sizeof(_leap_moments[0]); i++){ 163 | if (t < _leap_moments[i]) break; 164 | } 165 | return t + i; 166 | } 167 | 168 | time_t removeleapseconds(time_t t) 169 | { 170 | int i; 171 | for (i = 0; i < sizeof(_leap_moments) / sizeof(_leap_moments[0]); i++){ 172 | if (t < _leap_moments[i]) break; 173 | t--; 174 | } 175 | return t; 176 | } 177 | 178 | #define ITS_UTC_EPOCH 1072915200 179 | 180 | unsigned long mkitstime32(struct tm *tim_p) 181 | { 182 | time_t ret = mktaitime(tim_p); 183 | if (ret > 0){ 184 | ret -= ITS_UTC_EPOCH; 185 | } 186 | return (unsigned long)ret; 187 | } 188 | 189 | time_t mktaitime(struct tm *tim_p) 190 | { 191 | time_t t = mkgmtime(tim_p); 192 | if (t >= 0){ 193 | t = addleapseconds(t); 194 | } 195 | return t; 196 | } 197 | 198 | unsigned long unix2itstime32(time_t t) 199 | { 200 | return ((unsigned long) addleapseconds(t)) - ITS_UTC_EPOCH; 201 | } 202 | 203 | static char _datebuf[8][16]; 204 | static int _datebufidx = 0; 205 | const char * strgmtdate(time_t t) 206 | { 207 | struct tm * tm; 208 | char * b = _datebuf[_datebufidx]; 209 | _datebufidx = (_datebufidx + 1) & 7; 210 | 211 | tm = gmtime(&t); 212 | sprintf(b, "%u-%02u-%02u", 1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday); 213 | return b; 214 | } 215 | 216 | const char * strtaidate(time_t t) 217 | { 218 | return strgmtdate(removeleapseconds(t)); 219 | } 220 | 221 | const char * stritsdate32(time_t t) 222 | { 223 | return strtaidate(t + ITS_UTC_EPOCH); 224 | } 225 | 226 | time_t mkgmtime(struct tm *tim_p) 227 | { 228 | time_t tim = 0; 229 | long days = 0; 230 | int year, isdst, tm_isdst; 231 | 232 | /* validate structure */ 233 | validate_structure (tim_p); 234 | 235 | /* compute hours, minutes, seconds */ 236 | tim += tim_p->tm_sec + (tim_p->tm_min * _SEC_IN_MINUTE) + 237 | (tim_p->tm_hour * _SEC_IN_HOUR); 238 | 239 | /* compute days in year */ 240 | days += tim_p->tm_mday - 1; 241 | days += _DAYS_BEFORE_MONTH[tim_p->tm_mon]; 242 | if (tim_p->tm_mon > 1 && _DAYS_IN_YEAR (tim_p->tm_year) == 366) 243 | days++; 244 | 245 | /* compute day of the year */ 246 | tim_p->tm_yday = days; 247 | 248 | if (tim_p->tm_year > 10000 249 | || tim_p->tm_year < -10000) 250 | { 251 | return (time_t) -1; 252 | } 253 | 254 | /* compute days in other years */ 255 | if (tim_p->tm_year > 70) 256 | { 257 | for (year = 70; year < tim_p->tm_year; year++) 258 | days += _DAYS_IN_YEAR (year); 259 | } 260 | else if (tim_p->tm_year < 70) 261 | { 262 | for (year = 69; year > tim_p->tm_year; year--) 263 | days -= _DAYS_IN_YEAR (year); 264 | days -= _DAYS_IN_YEAR (year); 265 | } 266 | 267 | /* compute day of the week */ 268 | if ((tim_p->tm_wday = (days + 4) % 7) < 0) 269 | tim_p->tm_wday += 7; 270 | 271 | /* compute total seconds */ 272 | tim += (days * _SEC_IN_DAY); 273 | 274 | /* Convert user positive into 1 */ 275 | tm_isdst = tim_p->tm_isdst > 0 ? 1 : tim_p->tm_isdst; 276 | isdst = tm_isdst; 277 | 278 | //screw this! 279 | 280 | // if (_daylight) 281 | // { 282 | // int y = tim_p->tm_year + YEAR_BASE; 283 | // if (y == tz->__tzyear || __tzcalc_limits (y)) 284 | //{ 285 | // /* calculate start of dst in dst local time and 286 | // start of std in both std local time and dst local time */ 287 | // time_t startdst_dst = tz->__tzrule[0].change 288 | // - (time_t) tz->__tzrule[1].offset; 289 | // time_t startstd_dst = tz->__tzrule[1].change 290 | // - (time_t) tz->__tzrule[1].offset; 291 | // time_t startstd_std = tz->__tzrule[1].change 292 | // - (time_t) tz->__tzrule[0].offset; 293 | // /* if the time is in the overlap between dst and std local times */ 294 | // if (tim >= startstd_std && tim < startstd_dst) 295 | // ; /* we let user decide or leave as -1 */ 296 | // else 297 | // { 298 | // isdst = (tz->__tznorth 299 | // ? (tim >= startdst_dst && tim < startstd_std) 300 | // : (tim >= startdst_dst || tim < startstd_std)); 301 | // /* if user committed and was wrong, perform correction, but not 302 | // * if the user has given a negative value (which 303 | // * asks mktime() to determine if DST is in effect or not) */ 304 | // if (tm_isdst >= 0 && (isdst ^ tm_isdst) == 1) 305 | // { 306 | // /* we either subtract or add the difference between 307 | // time zone offsets, depending on which way the user got it 308 | // wrong. The diff is typically one hour, or 3600 seconds, 309 | // and should fit in a 16-bit int, even though offset 310 | // is a long to accomodate 12 hours. */ 311 | // int diff = (int) (tz->__tzrule[0].offset 312 | // - tz->__tzrule[1].offset); 313 | // if (!isdst) 314 | // diff = -diff; 315 | // tim_p->tm_sec += diff; 316 | // validate_structure (tim_p); 317 | // tim += diff; /* we also need to correct our current time calculation */ 318 | // } 319 | // } 320 | //} 321 | // } 322 | 323 | //screw this also 324 | /* add appropriate offset to put time in gmt format */ 325 | //if (isdst == 1) 326 | // tim += (time_t) tz->__tzrule[1].offset; 327 | //else /* otherwise assume std time */ 328 | // tim += (time_t) tz->__tzrule[0].offset; 329 | 330 | //and screw this too 331 | /* reset isdst flag to what we have calculated */ 332 | tim_p->tm_isdst = isdst; 333 | 334 | return tim; 335 | } 336 | 337 | // vim: ts=2 sw=2 et 338 | -------------------------------------------------------------------------------- /tests/mkgmtime.h: -------------------------------------------------------------------------------- 1 | /* lib/mkgmtime.h 2 | 3 | Copyright (C) 2010 DeSmuME team 4 | 5 | This file is part of DeSmuME 6 | 7 | DeSmuME is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | DeSmuME is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with DeSmuME; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | #ifndef _MKGMTIME_H_ 22 | #define _MKGMTIME_H_ 23 | 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | extern time_t mkgmtime(struct tm *tim_p); 31 | extern time_t mktaitime(struct tm *tim_p); 32 | extern time_t addleapseconds(time_t t); 33 | extern unsigned long mkitstime32(struct tm *tim_p); 34 | extern unsigned long unix2itstime32(time_t t); 35 | extern const char * stritsdate32(time_t t); 36 | extern const char * strtaidate(time_t t); 37 | extern const char * strgmtdate(time_t t); 38 | 39 | #ifdef __cplusplus 40 | } 41 | #endif 42 | 43 | #endif 44 | //_MKGMTIME_H_ 45 | -------------------------------------------------------------------------------- /tests/test_engine.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | This file is a part of FItsSec project: Implementation of ETSI TS 103 097 3 | Copyright (C) 2015 Denis Filatov (danya.filatov()gmail.com) 4 | 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed under GNU GPLv3 in the hope that it will 11 | be useful, but WITHOUT ANY WARRANTY; without even the implied warranty 12 | of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with Foobar. If not, see . 17 | @license GPL-3.0+ 18 | 19 | In particular cases this program can be distributed under other license 20 | by simple request to the author. 21 | *********************************************************************/ 22 | #define _CRT_SECURE_NO_WARNINGS 23 | 24 | #include "copts.h" 25 | #include "cstr.h" 26 | #include "fitsec.h" 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #ifdef WIN32 33 | #include 34 | #else 35 | #include 36 | #endif 37 | 38 | static FitSecConfig cfg1, cfg2; 39 | 40 | static const pchar_t* cfgfile = NULL; 41 | 42 | static FSLocation position = { 514743600, 56248900 }; 43 | static unsigned int _curTime = 0; 44 | static unsigned int _beginTime = 0; 45 | 46 | FILE * out; 47 | 48 | const char * outpath = "msg.log"; 49 | 50 | static copt_t options [] = { 51 | { "h?", "help", COPT_HELP, NULL, "Print this help page"}, 52 | { "C", "config", COPT_CFGFILE, &cfgfile, "Config file" }, 53 | { "s", "storage", COPT_STR, &cfg1.storage, "Storage directory" }, 54 | { "x", "hex", COPT_BOOL, &cfg1.hexadecimal, "Certificates are stored as hexadecimal stream" }, 55 | { "o", "out", COPT_STR, &outpath, "Output path" }, 56 | { NULL, NULL, COPT_END, NULL, NULL } 57 | }; 58 | 59 | static const char * _signer_types[] = { 60 | "self", 61 | "digest", 62 | "certificate", 63 | "chain", 64 | "other", 65 | }; 66 | 67 | 68 | static int SendMsg(const char * tn, FitSec * e, char * buf, FSMessageInfo * info); 69 | static int RecvMsg(const char * tn, FitSec * e, char * buf, int len, FSMessageInfo * info); 70 | 71 | static void print_x(FILE * f, const char * const ptr, int len); 72 | 73 | static const unsigned long _leap_moments[] = { 74 | 1136073600, 75 | 1230768000, 76 | 1341100800, 77 | 1435708800, 78 | }; 79 | 80 | static time_t addleapseconds(time_t t) 81 | { 82 | int i; 83 | for (i = 0; i < sizeof(_leap_moments) / sizeof(_leap_moments[0]); i++){ 84 | if (t < _leap_moments[i]) break; 85 | } 86 | return t + i; 87 | } 88 | 89 | #define ITS_UTC_EPOCH 1072915200 90 | 91 | static unsigned long unix2itstime32(time_t t) 92 | { 93 | return ((unsigned long) addleapseconds(t)) - ITS_UTC_EPOCH; 94 | } 95 | 96 | static int loadCertificates(FitSec * e, const pchar_t * _path, int hexadecimal); 97 | 98 | int main(int argc, char** argv) 99 | { 100 | FitSec * es, *er; 101 | char buf[1024]; 102 | int i, len; 103 | const char * testName; 104 | FSMessageInfo ms = { 0 }, mr = { 0 }; 105 | 106 | FitSecConfig_InitDefault(&cfg1); 107 | cfg1.storage = "CERTS1"; 108 | cfg1.hexadecimal = 1; 109 | 110 | int flags = COPT_DEFAULT | COPT_NOERR_UNKNOWN | COPT_NOAUTOHELP; 111 | argc = coptions(argc, argv, flags, options); 112 | if (COPT_ERC(argc)){ 113 | coptions_help(stdout, argv[0], 0, options, "Test"); 114 | return -1; 115 | } 116 | memcpy(&cfg2, &cfg1, sizeof(cfg1)); 117 | cfg2.storage = "CERTS2"; 118 | 119 | _curTime = unix2itstime32(time(NULL)); 120 | 121 | if (outpath){ 122 | out = fopen(outpath, "w"); 123 | if (out == NULL){ 124 | perror(outpath); 125 | return -1; 126 | } 127 | } 128 | else{ 129 | out = stdout; 130 | } 131 | 132 | // setup crypto alg 133 | cfg1.crypt = FSCryptEngineConfig_Default(); 134 | cfg2.crypt = FSCryptEngineConfig_Default(); 135 | 136 | es = FitSec_New(&cfg1); 137 | er = FitSec_New(&cfg2); 138 | if(0 >= loadCertificates(es, cfg1.storage, cfg1.hexadecimal)){ 139 | return -1; 140 | } 141 | if (0 >= loadCertificates(er, cfg2.storage, cfg2.hexadecimal)){ 142 | FitSec_Free(es); 143 | return -1; 144 | } 145 | 146 | ms.ssp.aid = 36; 147 | ms.position = position; 148 | ms.ssp.u.ssp.version = 1; 149 | ms.payloadType = FS_PAYLOAD_SIGNED; 150 | 151 | _beginTime = _curTime; 152 | 153 | // test 1: Send 20 CAM and read it 154 | 155 | testName = "testCAM"; 156 | ms.generationTime = ((Time64)_beginTime) * 1000; 157 | for (i = 0; i < 20; i++){ 158 | ms.generationTime += 300000; 159 | len = SendMsg(testName, es, buf, &ms); 160 | if (len > 0){ 161 | print_x(out, buf, len); 162 | RecvMsg(testName, er, buf, len, &mr); 163 | } 164 | } 165 | 166 | 167 | // test 2: Send 10 DENM and read it 168 | 169 | testName = "testDENM"; 170 | ms.generationTime = ((Time64)_beginTime) * 1000; 171 | ms.ssp.aid = 37; 172 | for (i = 0; i < 20; i++){ 173 | ms.generationTime += 300000; 174 | len = SendMsg(testName, es, buf, &ms); 175 | if (len > 0){ 176 | print_x(out, buf, len); 177 | RecvMsg(testName, er, buf, len, &mr); 178 | } 179 | } 180 | 181 | // test 3: Check unknown cert sending 182 | testName = "testCAM3"; 183 | ms.generationTime = ((Time64)_beginTime) * 1000; 184 | ms.ssp.aid = 36; 185 | len = SendMsg(testName, es, buf, &ms); 186 | len = SendMsg(testName, es, buf, &ms); 187 | if (len > 0){ 188 | print_x(out, buf, len); 189 | RecvMsg(testName, er, buf, len, &mr); 190 | len = SendMsg(testName, er, buf, &mr); 191 | RecvMsg(testName, es, buf, len, &ms); 192 | len = SendMsg(testName, es, buf, &ms); 193 | } 194 | 195 | FitSec_Free(es); 196 | FitSec_Free(er); 197 | 198 | return 0; 199 | } 200 | 201 | 202 | static int SendMsg(const char * tn, FitSec * e, char * buf, FSMessageInfo * info) 203 | { 204 | int ret; 205 | ret = FitSec_PrepareMessage(e, info, buf, 1024); 206 | if (ret > 0){ 207 | memcpy(&buf[ret], "0123456789", 10); 208 | info->payloadSize = 10; 209 | ret = FitSec_SignMessage(e, info, buf, 1024); 210 | } 211 | if (ret < 0){ 212 | fprintf(stderr, "SEND %s:\t ERROR: 0x%08X %s\n", tn, info->status, FitSec_ErrorMessage(info->status)); 213 | } 214 | else{ 215 | fprintf(stderr, "SEND %s:\t OK %s\n", tn, _signer_types[info->si_type]); 216 | } 217 | return ret; 218 | } 219 | 220 | static int RecvMsg(const char * tn, FitSec * e, char * buf, int len, FSMessageInfo * info) 221 | { 222 | int ret = FitSec_Verify(e, info, buf, len); 223 | if (!ret){ 224 | fprintf(stderr, "RECV %s:\t ERROR: 0x%08X %s\n", tn, info->status, FitSec_ErrorMessage(info->status)); 225 | } 226 | else{ 227 | #ifdef _MSC_VER 228 | fprintf(stderr, "RECV %s:\t %u ", tn, (unsigned int)(info->generationTime / 1000 - _beginTime)); 229 | fprintf(stderr, _signer_types[info->si_type]); 230 | fprintf(stderr, "\n"); 231 | #else 232 | fprintf(stderr, "RECV %s:\t %u %s\n", 233 | tn, (unsigned int)(info->generationTime / 1000 - _beginTime), 234 | _signer_types[info->si_type]); 235 | #endif 236 | } 237 | return ret; 238 | } 239 | 240 | static void print_x(FILE * f, const char * const ptr, int len) 241 | { 242 | const unsigned char * p = (const unsigned char *)ptr; 243 | const unsigned char * e = p + len; 244 | for (; p < e; p++){ 245 | fprintf(f, "%02X", *p); 246 | } 247 | } 248 | 249 | static char * _data; 250 | static int _dsize = 4096; 251 | static int _load_certificate(FitSec * e, pchar_t * path, pchar_t * fname, int hexadecimal) 252 | { 253 | char *data, *end; 254 | char *vkey = NULL, *ekey = NULL; 255 | int cert_len = 0, vkey_len = 0, ekey_len = 0; 256 | pchar_t *ext; 257 | int error = 0; 258 | 259 | data = _data; 260 | end = cstrnload(data, _dsize, path); 261 | if (end > data){ 262 | if (hexadecimal){ 263 | end = cstr_hex2bin(data, end - data, data, end - data); 264 | } 265 | cert_len = end - data; 266 | 267 | printf("%s:", fname); 268 | 269 | // look for keys 270 | ext = cstrpathextension(fname); 271 | pchar_cpy(ext, ".vkey"); 272 | vkey = end; 273 | end = cstrnload(vkey, _dsize - (vkey - data), path); 274 | if (end <= vkey){ 275 | end = vkey; vkey = NULL; 276 | } 277 | else{ 278 | if (hexadecimal){ 279 | end = cstr_hex2bin(vkey, end - vkey, vkey, end - vkey); 280 | } 281 | vkey_len = end - vkey; 282 | } 283 | 284 | pchar_cpy(ext, ".ekey"); 285 | ekey = end; 286 | end = cstrnload(ekey, _dsize - (ekey - data), path); 287 | if (end <= ekey){ 288 | end = ekey; ekey = NULL; 289 | } 290 | else{ 291 | if (hexadecimal){ 292 | end = cstr_hex2bin(ekey, end - ekey, ekey, end - ekey); 293 | } 294 | ekey_len = end - vkey; 295 | } 296 | FitSec_InstallCertificate(e, data, cert_len, vkey, vkey_len, ekey, ekey_len, &error); 297 | printf("%s\n", FitSec_ErrorMessage(error));; 298 | } 299 | else{ 300 | error = -1; 301 | printf("%s: Empty File\n", fname); 302 | } 303 | return error; 304 | } 305 | 306 | static int loadCertificates(FitSec * e, const pchar_t * _path, int hexadecimal) 307 | { 308 | size_t plen; 309 | pchar_t *path; 310 | int ccount = 0; 311 | 312 | plen = _path ? pchar_len(_path) : 0; 313 | path = malloc((plen + 256) * sizeof(pchar_t)); 314 | if (plen){ 315 | memcpy(path, _path, plen * sizeof(pchar_t)); 316 | while (plen && (path[plen - 1] == '/' || path[plen - 1] == '\\')) plen--; 317 | } 318 | if (plen == 0) path[plen++] = '.'; 319 | path[plen++] = '/'; 320 | path[plen] = 0; 321 | 322 | _data = malloc(_dsize); // it must not be more 323 | 324 | #ifdef WIN32 325 | { 326 | WIN32_FIND_DATA fd; 327 | HANDLE h; 328 | 329 | pchar_cpy(path + plen, "*.crt"); 330 | 331 | h = FindFirstFile(path, &fd); 332 | if (INVALID_HANDLE_VALUE != h){ 333 | do{ 334 | if (!(fd.dwFileAttributes& FILE_ATTRIBUTE_DIRECTORY)) { 335 | pchar_cpy(path + plen, fd.cFileName); 336 | if (0 <= _load_certificate(e, path, path + plen, hexadecimal)){ 337 | ccount++; 338 | } 339 | } 340 | } while (FindNextFile(h, &fd)); 341 | FindClose(h); 342 | } 343 | } 344 | #else 345 | { 346 | DIR * d; 347 | struct dirent * de; 348 | d = opendir(path); 349 | if(d){ 350 | while((de = readdir(d))){ 351 | pchar_t * ext = pchar_rchr(de->d_name, '.'); 352 | if(ext && 0 == strcmp(ext, ".crt")){ 353 | pchar_cpy(path + plen, de->d_name); 354 | if (0 <= _load_certificate(e, path, path + plen, hexadecimal)){ 355 | ccount++; 356 | } 357 | } 358 | } 359 | closedir(d); 360 | } 361 | } 362 | #endif 363 | free(path); 364 | free(_data); 365 | return ccount; 366 | } 367 | -------------------------------------------------------------------------------- /tests/test_engine.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {B51474B6-2547-4AAF-A038-796AE09D0327} 15 | Win32Proj 16 | test_engine 17 | 18 | 19 | 20 | Application 21 | true 22 | v120 23 | MultiByte 24 | 25 | 26 | Application 27 | false 28 | v120 29 | true 30 | MultiByte 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | true 44 | $(SolutionDir)build\MSVC-$(Configuration)\ 45 | $(SolutionDir)build\MSVC-$(Configuration)\obj\$(ProjectName)\ 46 | 47 | 48 | false 49 | $(SolutionDir)build\MSVC-$(Configuration)\ 50 | $(SolutionDir)build\MSVC-$(Configuration)\obj\$(ProjectName)\ 51 | 52 | 53 | 54 | 55 | 56 | Level3 57 | Disabled 58 | WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 59 | ../cshared;../libfitsec 60 | 61 | 62 | Console 63 | true 64 | 65 | 66 | 67 | 68 | Level3 69 | 70 | 71 | MaxSpeed 72 | true 73 | true 74 | WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 75 | ../cshared;../libfitsec 76 | 77 | 78 | Console 79 | true 80 | true 81 | true 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | {d5918b85-fa45-4f75-9b50-c2d3e34aba17} 90 | 91 | 92 | {3b631b0d-6665-43d9-825b-f562cf8048f9} 93 | 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /tools/mkunstats/fitsec_unstats.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fillabs/FITSec/9af584d21926c7ee0569c7bf51afc13e318e85d9/tools/mkunstats/fitsec_unstats.h -------------------------------------------------------------------------------- /tools/mkunstats/mkunstats.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "fitsec_unstats.h" 3 | 4 | int main(int argc, char ** argv){ 5 | int i; 6 | printf("static unsigned short _un_stats_regions[] = {"); 7 | for(i=0; i