mirror of
https://github.com/rsyslog/rsyslog.git
synced 2025-12-16 16:50:40 +01:00
Async service send timeout is not configurable and request cache size is too small to handle large amount of signing requests with small amount of permitted requests per aggregation round. For example user with max_requests = 4 results cache size 5 * max_requests or at least 256. When signing 300 log files cache will be too small resulting several unsigned blocks. When signing 200 log file cache will be adequate, but with rate of 4 signatures per second, it is only possible to sign 4 * 10 blocks before all requests that are not sent out will timeout. Fix for the issue is to make send timeout configurable and make the size of the cache depend on the value of send timeout. New configuration value sig.block.signtimeout="time, s" introduced that defines the time window wherein the block has to be signed. The size of the request cache is increased to 3 * max_requests * sign_timeout or at least 256.
247 lines
9.8 KiB
C
247 lines
9.8 KiB
C
/* lib_ksils12.h - rsyslog's KSI-LS12 support library
|
|
*
|
|
* Copyright 2013-2017 Adiscon GmbH and Guardtime, Inc.
|
|
*
|
|
* This file is part of rsyslog.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
* -or-
|
|
* see COPYING.ASL20 in the source distribution
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
#ifndef INCLUDED_KSILS12_H
|
|
#define INCLUDED_KSILS12_H
|
|
#include <ksi/ksi.h>
|
|
|
|
#include "lib_ksi_queue.h"
|
|
|
|
#define MAX_ROOTS 64
|
|
|
|
/* Flags and record types for TLV handling */
|
|
#define RSGT_FLAG_NONCRIT 0x20
|
|
#define RSGT_FLAG_FORWARD 0x40
|
|
#define RSGT_TYPE_MASK 0x1f
|
|
#define RSGT_FLAG_TLV16 0x80
|
|
|
|
/* check return state of operation and abort, if non-OK */
|
|
#define CHKr(code) if((r = code) != 0) goto done
|
|
|
|
/* check the return value of a ksi api call and log a message in case of error */
|
|
#define CHECK_KSI_API(code, context, msg) if((res = code) != 0) do { \
|
|
reportKSIAPIErr(context, NULL, msg, res); \
|
|
goto cleanup; \
|
|
} while (0)
|
|
|
|
|
|
typedef enum LOGSIG_SyncMode_en {
|
|
/** The block hashes and ksi signatures in one file */
|
|
LOGSIG_ASYNCHRONOUS = 0x00,
|
|
/** The block hashes and ksi signatures split into separate files */
|
|
LOGSIG_SYNCHRONOUS = 0x01
|
|
} LOGSIG_SyncMode;
|
|
|
|
enum {
|
|
/* Signer state assigned before the signer thread is initialized. State remains
|
|
* until thread initialization begins. In case of system failure to create new
|
|
* thread state remains the same.
|
|
*/
|
|
SIGNER_IDLE = 0x01,
|
|
|
|
/* Signer state assigned while signer thread initialization is in progress.
|
|
*/
|
|
SIGNER_INIT = 0x02,
|
|
|
|
/* Signer state assigned when signer thread is initialized and ready to work.
|
|
*/
|
|
SIGNER_STARTED = 0x04,
|
|
|
|
/* Thread state assigned when signer thread is being closed (signer thread returns).
|
|
*/
|
|
SIGNER_STOPPED = 0x08
|
|
};
|
|
|
|
/* Max number of roots inside the forest. This permits blocks of up to
|
|
* 2^MAX_ROOTS records. We assume that 64 is sufficient for all use
|
|
* cases ;) [and 64 is not really a waste of memory, so we do not even
|
|
* try to work with reallocs and such...]
|
|
*/
|
|
|
|
typedef struct rsksictx_s *rsksictx;
|
|
typedef struct ksifile_s *ksifile;
|
|
typedef struct ksierrctx_s ksierrctx_t;
|
|
|
|
|
|
/* context for gt calls. This primarily serves as a container for the
|
|
* config settings. The actual file-specific data is kept in ksifile.
|
|
*/
|
|
struct rsksictx_s {
|
|
KSI_CTX *ksi_ctx; /* libksi's context object */
|
|
KSI_DataHasher *hasher;
|
|
KSI_HashAlgorithm hashAlg;
|
|
KSI_HashAlgorithm hmacAlg;
|
|
uint8_t bKeepRecordHashes;
|
|
uint8_t bKeepTreeHashes;
|
|
uint64_t confInterval;
|
|
time_t tConfRequested;
|
|
uint64_t blockLevelLimit;
|
|
uint32_t blockTimeLimit;
|
|
uint32_t blockSigTimeout;
|
|
uint32_t effectiveBlockLevelLimit; /* level limit adjusted by gateway settings */
|
|
uint32_t threadSleepms;
|
|
uint8_t syncMode;
|
|
uid_t fileUID; /* IDs for creation */
|
|
uid_t dirUID;
|
|
gid_t fileGID;
|
|
gid_t dirGID;
|
|
int fCreateMode; /* mode to use when creating files */
|
|
int fDirCreateMode; /* mode to use when creating files */
|
|
char* aggregatorUri;
|
|
char* aggregatorId;
|
|
char* aggregatorKey;
|
|
char* aggregatorEndpoints[KSI_CTX_HA_MAX_SUBSERVICES];
|
|
int aggregatorEndpointCount;
|
|
char* random_source;
|
|
pthread_mutex_t module_lock;
|
|
pthread_t signer_thread;
|
|
ProtectedQueue *signer_queue;
|
|
int signer_state;
|
|
uint8_t disabled; /* permits to disable the plugin --> set to 1 */
|
|
|
|
ksifile *ksi; /* List of signature files for keeping track of block timeouts. */
|
|
size_t ksiCapacity;
|
|
size_t ksiCount;
|
|
|
|
char *debugFileName;
|
|
int debugLevel;
|
|
FILE *debugFile;
|
|
uint64_t max_requests;
|
|
void (*errFunc)(void *, unsigned char*);
|
|
void (*logFunc)(void *, unsigned char*);
|
|
void *usrptr; /* for error function */
|
|
};
|
|
|
|
/* this describes a file, as far as librsksi is concerned */
|
|
struct ksifile_s {
|
|
/* the following data items are mirrored from rsksictx to
|
|
* increase cache hit ratio (they are frequently accesed).
|
|
*/
|
|
KSI_HashAlgorithm hashAlg;
|
|
uint8_t bKeepRecordHashes;
|
|
uint8_t bKeepTreeHashes;
|
|
uint64_t blockSizeLimit;
|
|
uint32_t blockTimeLimit;
|
|
/* end mirrored properties */
|
|
uint8_t disabled; /* permits to disable this file --> set to 1 */
|
|
uint8_t *IV; /* initial value for blinding masks */
|
|
unsigned char lastLeaf[KSI_MAX_IMPRINT_LEN]; /* last leaf hash (maybe of previous block)
|
|
--> preserve on term */
|
|
unsigned char *blockfilename;
|
|
unsigned char *ksifilename;
|
|
unsigned char *statefilename;
|
|
uint64_t nRecords; /* current number of records in current block */
|
|
uint64_t bInBlk; /* are we currently inside a blk --> need to finish on close */
|
|
time_t blockStarted;
|
|
int8_t nRoots;
|
|
/* algo engineering: roots structure is split into two arrays
|
|
* in order to improve cache hits.
|
|
*/
|
|
KSI_DataHash *roots[MAX_ROOTS];
|
|
/* data members for the associated TLV file */
|
|
FILE *blockFile;
|
|
FILE *sigFile; /* Note that this may only be closed by signer thread or when signer thread has terminated. */
|
|
rsksictx ctx;
|
|
};
|
|
|
|
/* the following defines the ksistate file record. Currently, this record
|
|
* is fixed, we may change that over time.
|
|
*/
|
|
struct rsksistatefile {
|
|
char hdr[9]; /* must be "KSISTAT10" */
|
|
uint8_t hashID;
|
|
uint8_t lenHash;
|
|
/* after that, the hash value is contained within the file */
|
|
};
|
|
|
|
/* error states */
|
|
#define RSGTE_SUCCESS 0 /* Success state */
|
|
#define RSGTE_IO 1 /* any kind of io error */
|
|
#define RSGTE_FMT 2 /* data fromat error */
|
|
#define RSGTE_INVLTYP 3 /* invalid TLV type record (unexcpected at this point) */
|
|
#define RSGTE_OOM 4 /* ran out of memory */
|
|
#define RSGTE_LEN 5 /* error related to length records */
|
|
#define RSGTE_SIG_EXTEND 6/* error extending signature */
|
|
#define RSGTE_INVLD_RECCNT 7/* mismatch between actual records and records
|
|
given in block-sig record */
|
|
#define RSGTE_INVLHDR 8/* invalid file header */
|
|
#define RSGTE_EOF 9 /* specific EOF */
|
|
#define RSGTE_MISS_REC_HASH 10 /* record hash missing when expected */
|
|
#define RSGTE_MISS_TREE_HASH 11 /* tree hash missing when expected */
|
|
#define RSGTE_INVLD_REC_HASH 12 /* invalid record hash (failed verification) */
|
|
#define RSGTE_INVLD_TREE_HASH 13 /* invalid tree hash (failed verification) */
|
|
#define RSGTE_INVLD_REC_HASHID 14 /* invalid record hash ID (failed verification) */
|
|
#define RSGTE_INVLD_TREE_HASHID 15 /* invalid tree hash ID (failed verification) */
|
|
#define RSGTE_MISS_BLOCKSIG 16 /* block signature record missing when expected */
|
|
#define RSGTE_INVLD_SIGNATURE 17 /* Signature is invalid (KSI_Signature_verifyDataHash)*/
|
|
#define RSGTE_TS_CREATEHASH 18 /* error creating HASH (KSI_DataHash_create) */
|
|
#define RSGTE_TS_DERENCODE 19 /* error DER-Encoding a timestamp */
|
|
#define RSGTE_HASH_CREATE 20 /* error creating a hash */
|
|
#define RSGTE_END_OF_SIG 21 /* unexpected end of signature - more log line exist */
|
|
#define RSGTE_END_OF_LOG 22 /* unexpected end of log file - more signatures exist */
|
|
#define RSGTE_EXTRACT_HASH 23 /* error extracting hashes for record */
|
|
#define RSGTE_CONFIG_ERROR 24 /* Configuration error */
|
|
#define RSGTE_NETWORK_ERROR 25 /* Network error */
|
|
#define RSGTE_MISS_KSISIG 26 /* KSI signature missing */
|
|
#define RSGTE_INTERNAL 27 /* Internal error */
|
|
|
|
#define getIVLenKSI(bh) (hashOutputLengthOctetsKSI((bh)->hashID))
|
|
#define rsksiSetBlockLevelLimit(ctx, limit) ((ctx)->blockLevelLimit = (ctx)->effectiveBlockLevelLimit = limit)
|
|
#define rsksiSetBlockTimeLimit(ctx, limit) ((ctx)->blockTimeLimit = limit)
|
|
#define rsksiSetBlockSigTimeout(ctx, val) ((ctx)->blockSigTimeout = val)
|
|
#define rsksiSetConfInterval(ctx, val) ((ctx)->confInterval = val)
|
|
#define rsksiSetKeepRecordHashes(ctx, val) ((ctx)->bKeepRecordHashes = val)
|
|
#define rsksiSetKeepTreeHashes(ctx, val) ((ctx)->bKeepTreeHashes = val)
|
|
#define rsksiSetFileFormat(ctx, val) ((ctx)->fileFormat = val)
|
|
#define rsksiSetSyncMode(ctx, val) ((ctx)->syncMode = val)
|
|
#define rsksiSetRandomSource(ctx, val) ((ctx)->random_source = strdup(val))
|
|
#define rsksiSetFileUID(ctx, val) ((ctx)->fileUID = val) /* IDs for creation */
|
|
#define rsksiSetDirUID(ctx, val) ((ctx)->dirUID = val)
|
|
#define rsksiSetFileGID(ctx, val) ((ctx)->fileGID= val)
|
|
#define rsksiSetDirGID(ctx, val) ((ctx)->dirGID = val)
|
|
#define rsksiSetCreateMode(ctx, val) ((ctx)->fCreateMode= val)
|
|
#define rsksiSetDirCreateMode(ctx, val) ((ctx)->fDirCreateMode = val)
|
|
#define rsksiSetDebugLevel(ctx, val) ((ctx)->debugLevel = val)
|
|
|
|
|
|
int rsksiSetDebugFile(rsksictx ctx, char *val);
|
|
int rsksiSetAggregator(rsksictx ctx, char *uri, char *loginid, char *key);
|
|
int rsksiSetHashFunction(rsksictx ctx, char *algName);
|
|
int rsksiSetHmacFunction(rsksictx ctx, char *algName);
|
|
int rsksiInitModule(rsksictx ctx);
|
|
rsksictx rsksiCtxNew(void);
|
|
void rsksisetErrFunc(rsksictx ctx, void (*func)(void*, unsigned char *), void *usrptr);
|
|
void rsksisetLogFunc(rsksictx ctx, void (*func)(void*, unsigned char *), void *usrptr);
|
|
void reportKSIAPIErr(rsksictx ctx, ksifile ksi, const char *apiname, int ecode);
|
|
ksifile rsksiCtxOpenFile(rsksictx ctx, unsigned char *logfn);
|
|
int rsksifileDestruct(ksifile ksi);
|
|
void rsksiCtxDel(rsksictx ctx);
|
|
void sigblkInitKSI(ksifile ksi);
|
|
int sigblkAddRecordKSI(ksifile ksi, const unsigned char *rec, const size_t len);
|
|
int sigblkAddLeaf(ksifile ksi, const unsigned char *rec, const size_t len, bool metadata);
|
|
unsigned sigblkCalcLevel(unsigned leaves);
|
|
int sigblkFinishKSI(ksifile ksi);
|
|
int sigblkAddMetadata(ksifile ksi, const char *key, const char *value);
|
|
int sigblkCreateMask(ksifile ksi, KSI_DataHash **m);
|
|
int sigblkCreateHash(ksifile ksi, KSI_DataHash **r, const unsigned char *rec, const size_t len);
|
|
int sigblkHashTwoNodes(ksifile ksi, KSI_DataHash **node, KSI_DataHash *m, KSI_DataHash *r, uint8_t level);
|
|
|
|
#endif /* #ifndef INCLUDED_KSILS12_H */
|