├── .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