Core: SXT: using libndbuf, added external dependencies;

master
Alexander Vdolainen 6 years ago
parent e628f4a2fb
commit a01dd93bb8

@ -55,6 +55,7 @@ dnl checking fpr dependencies
PKG_CHECK_MODULES(OPENSSL, [openssl])
PKG_CHECK_MODULES(LIBTDATA, [libtdata >= 0.2.2])
PKG_CHECK_MODULES(LIBSEXPR, [libsexpr >= 1.3.1])
PKG_CHECK_MODULES(LIBNDBUF, [libndbuf])
case $host_os in
linux*) WIN32=no

@ -1,161 +0,0 @@
/*
* Secure eXtended Message Passing framework
* Secure eXtended Transport layer implementation: (libsxt)
* - very similar to SSH2/TLS
* - using already proven and tested crypto algos
* - better than TLS for message passing
*
* raw data buffer implementation used within library
*
* (c) Alexander Vdolainen 2016 <avdolainen@zoho.com>
*
* libsxmp is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 2.1 of the License, or
* (at your option) any later version.
*
* libsxmp is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.";
*
*/
#ifndef __SXT_RDB_H__
#define __SXT_RDB_H__
#include <stdarg.h>
#define SXTRDB_TERMINAT 0xdeadbeef
#define SXTRDB_BURN (1 << 1)
typedef struct __sxtrawdatabuffer_type {
char *raw;
uint32_t rlength; /* raw buffer allocated length */
uint32_t ulength; /* length of used allocated space */
uint32_t curr; /* cursor for read/write operations */
int flags;
} sxtrdb_t;
/* variadic macro workaround */
#define VA_APPLY_VARIADIC_MACRO(macro, tuple) macro tuple
#define __VA_NARG__(...) \
(__VA_NARG_(_0, ## __VA_ARGS__, __RSEQ_N()) - 1)
#define __VA_NARG_(...) \
VA_APPLY_VARIADIC_MACRO(__VA_ARG_N, (__VA_ARGS__))
#define __VA_ARG_N( \
_1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
_11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
_21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
_31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \
_41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
_51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
_61,_62,_63,N,...) N
#define __RSEQ_N() \
63, 62, 61, 60, \
59, 58, 57, 56, 55, 54, 53, 52, 51, 50, \
49, 48, 47, 46, 45, 44, 43, 42, 41, 40, \
39, 38, 37, 36, 35, 34, 33, 32, 31, 30, \
29, 28, 27, 26, 25, 24, 23, 22, 21, 20, \
19, 18, 17, 16, 15, 14, 13, 12, 11, 10, \
9, 8, 7, 6, 5, 4, 3, 2, 1, 0
/* allocation, freeing */
/* allocate raw buffer with defaults preallocation */
sxtrdb_t *sxtrdb_new(void);
/* will do the same as sxtrdb_new but will allocate given length */
sxtrdb_t *sxtrdb_new_palloc(uint32_t);
/* free all allocated space and buffer itself */
void sxtrdb_free(sxtrdb_t *);
/* read/write */
/* read different types, should return the size of the
* ridden data, otherwise error occurs */
uint32_t sxtrdb_read_u8(sxtrdb_t *, uint8_t *);
uint32_t sxtrdb_read_u16(sxtrdb_t *, uint16_t *);
uint32_t sxtrdb_read_u32(sxtrdb_t *, uint32_t *);
uint32_t sxtrdb_read_u64(sxtrdb_t *, uint64_t *);
/* get raw data, pointer must be allocated with at least required length,
* will return size of ridden data
*/
uint32_t sxtrdb_read_raw(sxtrdb_t *, void *, uint32_t);
/* write different types, should return the size of the
* written data, otherwise error occurs */
uint32_t sxtrdb_write_u8(sxtrdb_t *, uint8_t);
uint32_t sxtrdb_write_u16(sxtrdb_t *, uint16_t);
uint32_t sxtrdb_write_u32(sxtrdb_t *, uint32_t);
uint32_t sxtrdb_write_u64(sxtrdb_t *, uint64_t);
/* write raw data with the given length */
uint32_t sxtrdb_write_raw(sxtrdb_t *, void *, uint32_t);
/* write raw data *before* existing data */
uint32_t sxtrdb_write_raw_head(sxtrdb_t *, void *, uint32_t);
/* parse */
int sxtrdb_escan_va(sxtrdb_t *b, const char *fmt, int argc, va_list ap);
int sxtrdb_escan_wot(sxtrdb_t *b, const char *fmt, int argc, ...);
#define sxtrdb_escan(b, fmt, ...) \
sxtrdb_escan_wot((b), (fmt), __VA_NARG__(__VA_ARGS__), __VA_ARGS__, SXTRDB_TERMINAT)
/* print */
uint32_t sxtrdb_print_va(sxtrdb_t *b, const char *fmt, int argc, va_list ap);
uint32_t sxtrdb_print_wot(sxtrdb_t *b, const char *fmt, int argc, ...);
#define sxtrdb_print(b, fmt, ...) \
sxtrdb_print_wot((b), (fmt), __VA_NARG__(__VA_ARGS__), __VA_ARGS__, SXTRDB_TERMINAT)
/* misc */
/* returns length of used space in the buffer */
uint32_t sxtrdb_length(sxtrdb_t *);
/* set used length */
int sxtrdb_setlength(sxtrdb_t *, uint32_t);
/* returns length of allocated space in the buffer */
uint32_t sxtrdb_alength(sxtrdb_t *);
/* returns length of the left data to read */
uint32_t sxtrdb_leftlength(sxtrdb_t *);
/* reaturn a pointer to the raw data */
void *sxtrdb_rdata(sxtrdb_t *);
/* return pointer to the data currently being read/write */
void *sxtrdb_rdatacur(sxtrdb_t *);
/* set flags to the raw buffer */
void sxtrdb_setflags(sxtrdb_t *, int);
/* exchange flags for raw buff */
void sxtrdb_exflags(sxtrdb_t *, int);
/* reset current pointer */
void sxtrdb_resetcur(sxtrdb_t *);
/* reset all the flags */
#define sxtrdb_flagsreset(a) sxtrdb_exflags((a), 0)
/* compare buffers, returns 0 if equal */
int sxtrdb_cmp(sxtrdb_t *, sxtrdb_t *);
/* let the buffer to use actually used bytes, not all allocated space
* will return SXT_SUCCESS on success (or in case if it doesn't required),
* SXT_ENOMEM or other error if fails
*/
int sxtrdb_memopt(sxtrdb_t *);
#endif /* __SXT_RDB_H__ */

@ -44,7 +44,7 @@ typedef struct __sxtlink_type {
sxtkey_t *privkey;
/* peer stuff */
sxtrdb_t *loginpass_pair;
ndbuf_t *loginpass_pair;
sxtkey_t *peer_pubkey;
/* socket */

@ -133,7 +133,7 @@ int sxtkey_privkey_import_fbase64blob(const char *b64pk, uint8_t keytype,
int confirm, void *priv),
void *priv, sxtkey_t **ik);
int sxtkey_privkey_import_rdbuf(sxtrdb_t *buf, uint8_t keytype,
int sxtkey_privkey_import_rdbuf(ndbuf_t *buf, uint8_t keytype,
int (*ask_passkey)(char *pkbuf, size_t length,
int confirm, void *priv),
void *priv, sxtkey_t **ik);

@ -14,7 +14,7 @@ lib_LTLIBRARIES = libsxt.la
libsxt_la_SOURCES = \
core.c base64.c misc.c safebuffer.c rdb.c ppkp_ops.c \
core.c base64.c safebuffer.c ppkp_ops.c \
bcrypt.c blowfish.c ciphers.c lcrypt.c \
fe25519.c ge25519.c sc25519.c ed25519.c \
socket.c
@ -30,7 +30,7 @@ libsxt_la_LIBADD += -lmman -luuid /mingw64/lib/libtdata.a
else
libsxt_la_LIBADD += $(LIBUUID_LIBS) $(LIBTDATA_LIBS)
libsxt_la_LIBADD += $(LIBUUID_LIBS) $(LIBTDATA_LIBS) $(LIBNDBUF_LIBS)
endif !COND_WIN32

@ -51,12 +51,12 @@
#include <openssl/rand.h>
#include <tdata/list.h>
#include <ndbuf/ndbuf.h>
#include <sxt/errno.h>
#include <sxt/ciphers.h>
#include <sxt/lcrypt.h>
#include <sxt/safebuf.h>
#include <sxt/rdb.h>
#include <sxt/sxtkey.h>
#include <sxt/socket.h>
#include <sxt/sxt.h>

@ -9,7 +9,7 @@
#include <stdint.h>
#include <sys/types.h>
#include <sxt/ge25519.h>
#include <sxt/rdb.h>
#include <ndbuf/ndbuf.h>
#include <sxt/sxtkey.h>
#include <sxt/ciphers.h>
#include <sxt/lcrypt.h>

@ -1,49 +0,0 @@
/*
* Secure eXtended Message Passing framework
* Secure eXtended Transport layer implementation: (libsxt)
* - very similar to SSH2/TLS
* - using already proven and tested crypto algos
* - better than TLS for message passing
*
* (c) Alexander Vdolainen 2016 <avdolainen@zoho.com>
*
* libsxmp is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 2.1 of the License, or
* (at your option) any later version.
*
* libsxmp is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.";
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
uint64_t ntohll(uint64_t n)
{
#ifdef WORDS_BIGENDIAN
return n;
#else /* WORDS_BIGENDIAN */
return (((uint64_t)(n) << 56) | \
(((uint64_t)(n) << 40) & 0xff000000000000ULL) | \
(((uint64_t)(n) << 24) & 0xff0000000000ULL) | \
(((uint64_t)(n) << 8) & 0xff00000000ULL) | \
(((uint64_t)(n) >> 8) & 0xff000000ULL) | \
(((uint64_t)(n) >> 24) & 0xff0000ULL) | \
(((uint64_t)(n) >> 40) & 0xff00ULL) | \
((uint64_t)(n) >> 56));
#endif /* WORDS_BIGENDIAN */
}

@ -39,9 +39,10 @@
#include <openssl/err.h>
#include <openssl/engine.h>
#include <ndbuf/ndbuf.h>
#include <sxt/errno.h>
#include <sxt/safebuf.h>
#include <sxt/rdb.h>
#include <sxt/crypt.h>
#include <sxt/sxtkey.h>
#include <sxt/ed25519.h>
@ -55,9 +56,9 @@
/* locals */
static int sxtkey_export_priv_ed25519(const sxtkey_t *key, const char *pass, sxtsafebuffer_t **bin);
static int sxt_public_ed25519_2sb(const sxtkey_t *key, sxtsafebuffer_t **buf);
static int sxt_public_ed25519_2rdb(const sxtkey_t *key, sxtrdb_t **out);
static int sxt_public_ed25519_2rdb(const sxtkey_t *key, ndbuf_t **out);
static int _sxtkey_check_fmtrawbuf(const char *buffer);
static int _sxtkey_privkey_decrypt(sxtrdb_t *privkey, sxtrdb_t *kdfopt, const char *passkey);
static int _sxtkey_privkey_decrypt(ndbuf_t *privkey, ndbuf_t *kdfopt, const char *passkey);
int sxtkey_generate(sxtkey_t *key, int type, int opt)
{
@ -435,15 +436,15 @@ int sxtkey_import_priv_file(const char *file, const char *passkey,
return r;
}
int sxtkey_privkey_import_rdbuf(sxtrdb_t *buf, uint8_t keytype,
int sxtkey_privkey_import_rdbuf(ndbuf_t *buf, uint8_t keytype,
int (*ask_passkey)(char *pkbuf, size_t length,
int confirm, void *priv),
void *priv, sxtkey_t **ik)
{
uint8_t flags = 0, chk = 0;
char *passkey = NULL;
sxtrdb_t *kdfopt = NULL, *ctrl_pubkey = NULL, *privkey = NULL;
sxtrdb_t *ed25519_pubbuf = NULL, *ed25519_privbuf = NULL;
ndbuf_t *kdfopt = NULL, *ctrl_pubkey = NULL, *privkey = NULL;
ndbuf_t *ed25519_pubbuf = NULL, *ed25519_privbuf = NULL;
sxtkey_t *key = NULL;
char *keyname = NULL, *ciphername = NULL, *kdfname = NULL, *magic = NULL;
uint64_t hash = 0;
@ -451,10 +452,10 @@ int sxtkey_privkey_import_rdbuf(sxtrdb_t *buf, uint8_t keytype,
int r = SXT_SUCCESS, decrypt = 0;
if(!buf) return SXT_EINVAL;
if(!sxtrdb_length(buf)) return SXT_EINVAL;
if(!ndbuf_length(buf)) return SXT_EINVAL;
if(keytype == 0) return SXT_EKEY;
r = sxtrdb_escan(buf, "sbsssRdRR", &magic, &flags, &keyname, &ciphername, &kdfname,
r = ndbuf_escan(buf, "sbsssRdRR", &magic, &flags, &keyname, &ciphername, &kdfname,
&kdfopt, &ctrl_pklen, &ctrl_pubkey, &privkey);
if(r != SXT_SUCCESS) goto __failed;
@ -507,7 +508,7 @@ int sxtkey_privkey_import_rdbuf(sxtrdb_t *buf, uint8_t keytype,
}
}
/* here we have privkey decrypted */
r = sxtrdb_escan(privkey, "ddRRqb", &r1, &r2, &ed25519_pubbuf, &ed25519_privbuf, &hash, &chk);
r = ndbuf_escan(privkey, "ddRRqb", &r1, &r2, &ed25519_pubbuf, &ed25519_privbuf, &hash, &chk);
if(r != SXT_SUCCESS) {
hash = 0;
chk = 0;
@ -518,10 +519,10 @@ int sxtkey_privkey_import_rdbuf(sxtrdb_t *buf, uint8_t keytype,
if(r1 != r2) goto __invalid;
/* control check of public keys */
if(sxtrdb_cmp(ctrl_pubkey, ed25519_pubbuf)) {
if(ndbuf_cmp(ctrl_pubkey, ed25519_pubbuf)) {
__invalid:
sxtrdb_free(ed25519_pubbuf);
sxtrdb_free(ed25519_privbuf);
ndbuf_free(ed25519_pubbuf);
ndbuf_free(ed25519_privbuf);
r = SXT_EKEY;
goto __failed;
}
@ -529,8 +530,8 @@ int sxtkey_privkey_import_rdbuf(sxtrdb_t *buf, uint8_t keytype,
/* alloc a key and copy data */
if(!(key = sxtkey_alloc())) {
__enomem:
sxtrdb_free(ed25519_pubbuf);
sxtrdb_free(ed25519_privbuf);
ndbuf_free(ed25519_pubbuf);
ndbuf_free(ed25519_privbuf);
r = SXT_ENOMEM;
goto __failed;
}
@ -544,11 +545,11 @@ int sxtkey_privkey_import_rdbuf(sxtrdb_t *buf, uint8_t keytype,
goto __enomem;
}
/* copy and set all required data */
memcpy(key->pubkey, sxtrdb_rdata(ed25519_pubbuf), ED25519_PK_LEN);
memcpy(key->privkey, sxtrdb_rdata(ed25519_privbuf), ED25519_SK_LEN);
memcpy(key->pubkey, ndbuf_rdata(ed25519_pubbuf), ED25519_PK_LEN);
memcpy(key->privkey, ndbuf_rdata(ed25519_privbuf), ED25519_SK_LEN);
/* free it */
sxtrdb_free(ed25519_pubbuf);
sxtrdb_free(ed25519_privbuf);
ndbuf_free(ed25519_pubbuf);
ndbuf_free(ed25519_privbuf);
key->type = keytype;
key->hash = hash;
key->flags = SXT_PPKP_PRIVATE;
@ -573,9 +574,9 @@ int sxtkey_privkey_import_rdbuf(sxtrdb_t *buf, uint8_t keytype,
memset(passkey, 0, 64);
free(passkey);
}
if(kdfopt) sxtrdb_free(kdfopt);
if(ctrl_pubkey) sxtrdb_free(ctrl_pubkey);
if(privkey) sxtrdb_free(privkey);
if(kdfopt) ndbuf_free(kdfopt);
if(ctrl_pubkey) ndbuf_free(ctrl_pubkey);
if(privkey) ndbuf_free(privkey);
return r;
}
@ -585,7 +586,7 @@ int sxtkey_privkey_import_fbase64blob(const char *b64pk, uint8_t keytype,
int confirm, void *priv),
void *priv, sxtkey_t **ik)
{
sxtrdb_t *fullkeybuf = NULL;
ndbuf_t *fullkeybuf = NULL;
char *decoded = NULL;
int len, r = SXT_SUCCESS;
@ -604,11 +605,11 @@ int sxtkey_privkey_import_fbase64blob(const char *b64pk, uint8_t keytype,
}
/* allocate a buffer and insert raw data */
if(!(fullkeybuf = sxtrdb_new())) {
if(!(fullkeybuf = ndbuf_new())) {
r = SXT_ENOMEM;
goto __failed;
} else sxtrdb_setflags(fullkeybuf, SXTRDB_BURN);
sxtrdb_write_raw_head(fullkeybuf, decoded, len);
} else ndbuf_setflags(fullkeybuf, NDBUF_BURN);
ndbuf_write_raw_head(fullkeybuf, decoded, len);
r = sxtkey_privkey_import_rdbuf(fullkeybuf, keytype, ask_passkey, priv, ik);
@ -617,7 +618,7 @@ int sxtkey_privkey_import_fbase64blob(const char *b64pk, uint8_t keytype,
memset(decoded, 0, len);
free(decoded);
}
if(fullkeybuf) sxtrdb_free(fullkeybuf);
if(fullkeybuf) ndbuf_free(fullkeybuf);
return r;
}
@ -626,7 +627,7 @@ int sxtkey_pubkey_import_fbase64blob(const char *b64b, uint8_t keytype,
uint64_t ctrl_hash, sxtkey_t **ik)
{
sxtkey_t *key = NULL;
sxtrdb_t *keybuf = NULL;
ndbuf_t *keybuf = NULL;
char *blob = NULL, *ed25519pk = NULL;
uint64_t hash;
uint32_t klen = 0;
@ -641,7 +642,7 @@ int sxtkey_pubkey_import_fbase64blob(const char *b64b, uint8_t keytype,
else memset(blob, 0, len);
len = sxt_b64decode_in(b64b, len - 1, blob, len);
if(!(keybuf = sxtrdb_new())) {
if(!(keybuf = ndbuf_new())) {
r = SXT_ENOMEM;
goto __failed;
}
@ -653,9 +654,9 @@ int sxtkey_pubkey_import_fbase64blob(const char *b64b, uint8_t keytype,
goto __failed;
}
/* <pubkey><hash> */
sxtrdb_write_raw(keybuf, blob, len);
sxtrdb_resetcur(keybuf);
sxtrdb_escan(keybuf, "dpq", &klen, ED25519_PK_LEN, ed25519pk, &hash);
ndbuf_write_raw(keybuf, blob, len);
ndbuf_resetcur(keybuf);
ndbuf_escan(keybuf, "dpq", &klen, ED25519_PK_LEN, ed25519pk, &hash);
if(klen != ED25519_PK_LEN) {
r = SXT_EKEY;
@ -687,7 +688,7 @@ int sxtkey_pubkey_import_fbase64blob(const char *b64b, uint8_t keytype,
__failed:
if(blob) free(blob);
if(keybuf) sxtrdb_free(keybuf);
if(keybuf) ndbuf_free(keybuf);
if(ed25519pk) free(ed25519pk);
return r;
@ -697,7 +698,7 @@ int sxtkey_import_public_file(const char *file, sxtkey_t **ik)
{
FILE *stream = NULL;
char *rawfbuf = NULL, *tbuf, *tebuf, *tuple = NULL, *b64pk = NULL;
sxtrdb_t *chbuf = NULL;
ndbuf_t *chbuf = NULL;
int tc = 0, tcc = 0, len;
struct stat stbuf;
int r = SXT_ENOMEM;
@ -827,14 +828,14 @@ int sxtkey_import_public_file(const char *file, sxtkey_t **ik)
len = sxt_b64decode_in(tuple, strlen(tuple), tebuf, len);
free(tuple);
if(!(chbuf = sxtrdb_new())) {
if(!(chbuf = ndbuf_new())) {
free(tebuf);
r = SXT_ENOMEM; goto __failed;
}
sxtrdb_write_raw(chbuf, tebuf, len);
sxtrdb_resetcur(chbuf);
sxtrdb_read_u64(chbuf, &ctrl_hash);
sxtrdb_free(chbuf);
ndbuf_write_raw(chbuf, tebuf, len);
ndbuf_resetcur(chbuf);
ndbuf_read_u64(chbuf, &ctrl_hash);
ndbuf_free(chbuf);
free(tebuf);
tebuf = tuple = NULL;
tcc++;
@ -921,7 +922,7 @@ int sxtkey_export_priv_file(const sxtkey_t *key, const char *file, const char *p
static int sxtkey_publickey2blob_whash(const sxtkey_t *key, sxtsafebuffer_t **o)
{
sxtsafebuffer_t *buf = NULL, *pk = NULL;
sxtrdb_t *b = NULL;
ndbuf_t *b = NULL;
int r = SXT_SUCCESS;
if(!key) return SXT_EINVAL;
@ -935,23 +936,23 @@ static int sxtkey_publickey2blob_whash(const sxtkey_t *key, sxtsafebuffer_t **o)
default: return SXT_EKEY;
}
if(!(b = sxtrdb_new())) {
if(!(b = ndbuf_new())) {
r = SXT_ENOMEM;
goto __failed;
}
sxtrdb_print(b, "pq", sxtsafebuffer_length(pk), sxtsafebuffer_getdata(pk),
ndbuf_print(b, "pq", sxtsafebuffer_length(pk), sxtsafebuffer_getdata(pk),
key->hash);
if(!(buf = sxtsafebuffer_new(sxtrdb_length(b)))) {
if(!(buf = sxtsafebuffer_new(ndbuf_length(b)))) {
r = SXT_ENOMEM;
goto __failed;
}
memcpy(sxtsafebuffer_getdata(buf), sxtrdb_rdata(b), sxtrdb_length(b));
memcpy(sxtsafebuffer_getdata(buf), ndbuf_rdata(b), ndbuf_length(b));
*o = buf;
__failed:
if(pk) sxtsafebuffer_destroy(pk);
if(b) sxtrdb_free(b);
if(b) ndbuf_free(b);
return r;
}
@ -959,24 +960,24 @@ static int sxtkey_publickey2blob_whash(const sxtkey_t *key, sxtsafebuffer_t **o)
static int sxtkey_hash2blob(const sxtkey_t *key, sxtsafebuffer_t **o)
{
sxtsafebuffer_t *buf = NULL;
sxtrdb_t *b = NULL;
ndbuf_t *b = NULL;
int r = SXT_SUCCESS;
if(!key) return SXT_EINVAL;
if(!(b = sxtrdb_new())) return SXT_ENOMEM;
if(!(b = ndbuf_new())) return SXT_ENOMEM;
sxtrdb_print(b, "q", key->hash);
if(!(buf = sxtsafebuffer_new(sxtrdb_length(b)))) {
ndbuf_print(b, "q", key->hash);
if(!(buf = sxtsafebuffer_new(ndbuf_length(b)))) {
r = SXT_ENOMEM;
goto __failed;
}
memcpy(sxtsafebuffer_getdata(buf), sxtrdb_rdata(b), sxtrdb_length(b));
memcpy(sxtsafebuffer_getdata(buf), ndbuf_rdata(b), ndbuf_length(b));
*o = buf;
__failed:
if(b) sxtrdb_free(b);
if(b) ndbuf_free(b);
return r;
}
@ -1053,8 +1054,8 @@ static int sxtkey_export_priv_ed25519(const sxtkey_t *key, const char *pass, sxt
{
int r = 0;
sxtsafebuffer_t *b64 = NULL, *pubkey_sb = NULL;
sxtrdb_t *keybuf = NULL, *privbuf = NULL;
sxtrdb_t *kdfopts = NULL;
ndbuf_t *keybuf = NULL, *privbuf = NULL;
ndbuf_t *kdfopts = NULL;
uint32_t urand;
uint8_t flags = 0;
@ -1062,8 +1063,8 @@ static int sxtkey_export_priv_ed25519(const sxtkey_t *key, const char *pass, sxt
if(key->type != PPKP_ED25519) return SXT_EKEY;
/* allocate a buffer for the key at all */
if(!(keybuf = sxtrdb_new())) return SXT_ENOMEM;
else sxtrdb_setflags(keybuf, SXTRDB_BURN);
if(!(keybuf = ndbuf_new())) return SXT_ENOMEM;
else ndbuf_setflags(keybuf, NDBUF_BURN);
/* ok firstly get private-key-data according to SXT key container doc */
if((r = sxt_public_ed25519_2sb(key, &pubkey_sb)) != SXT_SUCCESS) goto __failed;
@ -1071,19 +1072,19 @@ static int sxtkey_export_priv_ed25519(const sxtkey_t *key, const char *pass, sxt
/* now we need random number */
sxt_get_random(&urand, sizeof(uint32_t), 1);
if(!(privbuf = sxtrdb_new())) {
if(!(privbuf = ndbuf_new())) {
r = SXT_ENOMEM;
goto __failed;
} else sxtrdb_setflags(privbuf, SXTRDB_BURN);
} else ndbuf_setflags(privbuf, NDBUF_BURN);
/* two random numbers */
if(!sxtrdb_print(privbuf, "dd", urand, urand)) {
if(!ndbuf_print(privbuf, "dd", urand, urand)) {
r = SXT_ENOMEM;
goto __failed;
}
/* pub, priv, hash, zero padding */
if(!sxtrdb_print(privbuf, "dpdpqb", (uint32_t)ED25519_PK_LEN, (size_t)ED25519_PK_LEN,
if(!ndbuf_print(privbuf, "dpdpqb", (uint32_t)ED25519_PK_LEN, (size_t)ED25519_PK_LEN,
key->pubkey, (uint32_t)ED25519_SK_LEN, (size_t)ED25519_SK_LEN,
key->privkey, key->hash, (uint8_t)'\0')) {
r = SXT_ENOMEM;
@ -1122,16 +1123,16 @@ static int sxtkey_export_priv_ed25519(const sxtkey_t *key, const char *pass, sxt
} else sxt_get_random(sxtsafebuffer_getdata(salt), 16, 1);
/* generate kdf description <salt><rounds> */
if(!(kdfopts = sxtrdb_new())) {
if(!(kdfopts = ndbuf_new())) {
sxtsafebuffer_destroy(salt);
goto __enomem1;
}
sxtrdb_print(kdfopts, "Pd", 16, sxtsafebuffer_getdata(salt), (uint32_t)32);
ndbuf_print(kdfopts, "Pd", 16, sxtsafebuffer_getdata(salt), (uint32_t)32);
/* ok, now we need to get a padding, just to be sure to be aligned for the
cipher block size */
while(sxtrdb_length(privbuf) % cipher->blksize != 0) {
if(sxtrdb_write_u8(privbuf, pad) != sizeof(uint8_t)) {
while(ndbuf_length(privbuf) % cipher->blksize != 0) {
if(ndbuf_write_u8(privbuf, pad) != sizeof(uint8_t)) {
sxt_cipher_free(cipher);
r = SXT_ENOMEM;
goto __failed;
@ -1157,7 +1158,7 @@ static int sxtkey_export_priv_ed25519(const sxtkey_t *key, const char *pass, sxt
/* encrypt with cipher */
sxt_cipher_set_encrypt_key(cipher, keystub, keystub + cipher->keysize/8);
sxt_cipher_encrypt(cipher, sxtrdb_rdata(privbuf), sxtrdb_rdata(privbuf), sxtrdb_length(privbuf));
sxt_cipher_encrypt(cipher, ndbuf_rdata(privbuf), ndbuf_rdata(privbuf), ndbuf_length(privbuf));
/* clean up all */
memset(keystub, 0, sizeof(keystub));
@ -1167,11 +1168,11 @@ static int sxtkey_export_priv_ed25519(const sxtkey_t *key, const char *pass, sxt
/* in case of non-crypted key we anyways should include encrypt options */
if(!kdfopts) {
if(!(kdfopts = sxtrdb_new())) {
if(!(kdfopts = ndbuf_new())) {
r = SXT_ENOMEM;
goto __failed;
}
sxtrdb_print(kdfopts, "Pd", 3, "nil", (uint32_t)0);
ndbuf_print(kdfopts, "Pd", 3, "nil", (uint32_t)0);
}
/* there are a time to print all required content to the buffer */
@ -1181,37 +1182,37 @@ static int sxtkey_export_priv_ed25519(const sxtkey_t *key, const char *pass, sxt
* <private-key-data>
* according to the documentation
*/
sxtrdb_print(keybuf, "sbsssPPP", PPKP_MAGIC, flags, "ppkp-ed25519",
ndbuf_print(keybuf, "sbsssPPP", PPKP_MAGIC, flags, "ppkp-ed25519",
pass ? "aes128-cbc" : "nil", pass ? "bcrypt" : "nil",
sxtrdb_length(kdfopts), sxtrdb_rdata(kdfopts),
ndbuf_length(kdfopts), ndbuf_rdata(kdfopts),
sxtsafebuffer_length(pubkey_sb), sxtsafebuffer_getdata(pubkey_sb),
sxtrdb_length(privbuf), sxtrdb_rdata(privbuf));
ndbuf_length(privbuf), ndbuf_rdata(privbuf));
/* as described - encode all with base64 */
b64 = sxtsafebuffer_new(sxt_rawlen2b64len(sxtrdb_length(keybuf)));
b64 = sxtsafebuffer_new(sxt_rawlen2b64len(ndbuf_length(keybuf)));
if(!b64) {
r = SXT_ENOMEM;
goto __failed;
}
/* encode buffer */
sxt_b64encode_in((const char *)sxtrdb_rdata(keybuf), (char *)sxtsafebuffer_getdata(b64),
sxtrdb_length(keybuf));
sxt_b64encode_in((const char *)ndbuf_rdata(keybuf), (char *)sxtsafebuffer_getdata(b64),
ndbuf_length(keybuf));
/* the last ... */
*bin = b64;
r = SXT_SUCCESS;
__failed:
if(keybuf) sxtrdb_free(keybuf); /* container free */
if(keybuf) ndbuf_free(keybuf); /* container free */
if(pubkey_sb) sxtsafebuffer_destroy(pubkey_sb); /* public key bin free */
if(privbuf) sxtrdb_free(privbuf); /* private key buffer free */
if(privbuf) ndbuf_free(privbuf); /* private key buffer free */
return r;
}
static int sxt_public_ed25519_2sb(const sxtkey_t *key, sxtsafebuffer_t **buf)
{
sxtrdb_t *rbuf = NULL;
ndbuf_t *rbuf = NULL;
sxtsafebuffer_t *o = NULL;
int r = SXT_SUCCESS;
@ -1220,31 +1221,31 @@ static int sxt_public_ed25519_2sb(const sxtkey_t *key, sxtsafebuffer_t **buf)
r = sxt_public_ed25519_2rdb(key, &rbuf);
if(!rbuf) return r;
if(!(o = sxtsafebuffer_new((size_t)sxtrdb_length(rbuf)))) {
if(!(o = sxtsafebuffer_new((size_t)ndbuf_length(rbuf)))) {
r = SXT_ENOMEM;
goto __failed;
}
sxtsafebuffer_setdata(o, sxtrdb_rdata(rbuf), (size_t)sxtrdb_length(rbuf));
sxtsafebuffer_setdata(o, ndbuf_rdata(rbuf), (size_t)ndbuf_length(rbuf));
*buf = o;
__failed:
sxtrdb_free(rbuf);
ndbuf_free(rbuf);
return r;
}
static int sxt_public_ed25519_2rdb(const sxtkey_t *key, sxtrdb_t **out)
static int sxt_public_ed25519_2rdb(const sxtkey_t *key, ndbuf_t **out)
{
sxtrdb_t *buf = NULL;
ndbuf_t *buf = NULL;
if(!key->pubkey) return SXT_EKEY;
if(!(buf = sxtrdb_new())) return SXT_ENOMEM;
else sxtrdb_setflags(buf, SXTRDB_BURN);
if(!(buf = ndbuf_new())) return SXT_ENOMEM;
else ndbuf_setflags(buf, NDBUF_BURN);
if(!sxtrdb_print(buf, "dp", (uint32_t)ED25519_PK_LEN, (size_t)ED25519_PK_LEN,
if(!ndbuf_print(buf, "dp", (uint32_t)ED25519_PK_LEN, (size_t)ED25519_PK_LEN,
key->pubkey)) {
sxtrdb_free(buf);
ndbuf_free(buf);
return SXT_EKEY;
}
@ -1286,11 +1287,11 @@ static int _sxtkey_check_fmtrawbuf(const char *buffer)
return r;
}
static int _sxtkey_privkey_decrypt(sxtrdb_t *privkey, sxtrdb_t *kdfopt,
static int _sxtkey_privkey_decrypt(ndbuf_t *privkey, ndbuf_t *kdfopt,
const char *passkey)
{
int r = SXT_SUCCESS;
sxtrdb_t *salt = NULL;
ndbuf_t *salt = NULL;
sxt_cipher_t *cipher = sxt_cipher_get("aes128-cbc");
uint32_t rounds, keystub_len;
uint8_t keystub[128];
@ -1303,11 +1304,11 @@ static int _sxtkey_privkey_decrypt(sxtrdb_t *privkey, sxtrdb_t *kdfopt,
if(!(cipher = sxt_cipher_get("aes128-cbc"))) return SXT_EKEY;
/* get salt and rounds */
if((r = sxtrdb_escan(kdfopt, "Rd", &salt, &rounds)) != SXT_SUCCESS)
if((r = ndbuf_escan(kdfopt, "Rd", &salt, &rounds)) != SXT_SUCCESS)
goto __failed;
/* check blob length and cipher block size */
if(sxtrdb_length(privkey) % cipher->blksize != 0) {
if(ndbuf_length(privkey) % cipher->blksize != 0) {
r = SXT_EKEY;
goto __failed;
}
@ -1318,7 +1319,7 @@ static int _sxtkey_privkey_decrypt(sxtrdb_t *privkey, sxtrdb_t *kdfopt,
r = SXT_EKEY;
goto __failed;
}
if(bcrypt_pbkdf(passkey, strlen(passkey), sxtrdb_rdata(salt), sxtrdb_length(salt),
if(bcrypt_pbkdf(passkey, strlen(passkey), ndbuf_rdata(salt), ndbuf_length(salt),
keystub, keystub_len, rounds) < 0) {
memset(keystub, 0, keystub_len);
r = SXT_EAUTH;
@ -1327,15 +1328,15 @@ static int _sxtkey_privkey_decrypt(sxtrdb_t *privkey, sxtrdb_t *kdfopt,
/* set decrypt key and decrypt */
cipher->f->set_decrypt_key(cipher, keystub, keystub + cipher->keysize/8);
cipher->f->decrypt(cipher, sxtrdb_rdata(privkey), sxtrdb_rdata(privkey),
sxtrdb_length(privkey));
cipher->f->decrypt(cipher, ndbuf_rdata(privkey), ndbuf_rdata(privkey),
ndbuf_length(privkey));
/* free/burn unused data */
memset(keystub, 0, keystub_len);
__failed:
if(cipher) sxt_cipher_free(cipher);
if(salt) sxtrdb_free(salt);
if(salt) ndbuf_free(salt);
return r;
}

@ -1,748 +0,0 @@
/*
* Secure eXtended Message Passing framework
* Secure eXtended Transport layer implementation: (libsxt)
* - very similar to SSH2/TLS
* - using already proven and tested crypto algos
* - better than TLS for message passing
*
* raw data buffer implementation used within library
*
* (c) Alexander Vdolainen 2016 <avdolainen@zoho.com>
*
* libsxmp is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 2.1 of the License, or
* (at your option) any later version.
*
* libsxmp is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.";
*
*/
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <arpa/inet.h>
#include <sxt/errno.h>
#include <sxt/rdb.h>
extern uint64_t ntohll(uint64_t n);
/* allocation, freeing */
#define DEFAULT_PREALLOC_SIZE 256
#define SXTBUF_MAXLENGTH 6*(1024*1024)
/* allocate raw buffer with defaults preallocation */
sxtrdb_t *sxtrdb_new(void)
{
sxtrdb_t *b = malloc(sizeof(sxtrdb_t));
if(!b) return NULL;
if(!(b->raw = malloc(DEFAULT_PREALLOC_SIZE))) {
free(b);
b = NULL;
} else {
b->rlength = DEFAULT_PREALLOC_SIZE;
b->ulength = b->curr = 0;
b->flags = 0;
}
return b;
}
/* will do the same as sxtrdb_new but will allocate given length */
sxtrdb_t *sxtrdb_new_palloc(uint32_t alen)
{
sxtrdb_t *b = NULL;
if(alen > SXTBUF_MAXLENGTH) return NULL;
if(!(b = malloc(sizeof(sxtrdb_t)))) return NULL;
else memset(b, 0, sizeof(sxtrdb_t));
if(!(b->raw = malloc(alen))) {
free(b);
b = NULL;
} else b->rlength = alen;
return b;
}
/* free all allocated space and buffer itself */
void sxtrdb_free(sxtrdb_t *b)
{
if(!b) return;
if(b->flags & SXTRDB_BURN) {
if(b->raw) memset(b->raw, 0, b->rlength);
memset(b, 0, sizeof(sxtrdb_t));
}
if(b->raw) free(b->raw);
free(b);
return;
}
/* read/write */
/* read different types, should return the size of the
* ridden data, otherwise error occurs */
uint32_t sxtrdb_read_u8(sxtrdb_t *b, uint8_t *o)
{
uint8_t u;
if(!b || !o) return 0;
if(!b->raw) return 0;
if(b->curr >= b->ulength) return 0;
u = *((uint8_t*)(b->raw + b->curr));
b->curr += sizeof(uint8_t);
*o = u;
return sizeof(uint8_t);
}
uint32_t sxtrdb_read_u16(sxtrdb_t *b, uint16_t *o)
{
uint16_t u;
if(!b || !o) return 0;
if(!b->raw) return 0;
if(b->curr >= b->ulength) return 0;
if(b->curr + sizeof(uint16_t) > b->ulength) return 0;
u = *((uint16_t *)(b->raw + b->curr));
b->curr += sizeof(uint16_t);
*o = ntohs(u);
return sizeof(uint16_t);
}
uint32_t sxtrdb_read_u32(sxtrdb_t *b, uint32_t *o)
{
uint32_t u;
if(!b || !o) return 0;
if(!b->raw) return 0;
if(b->curr >= b->ulength) return 0;
if(b->curr + sizeof(uint32_t) > b->ulength) return 0;
u = *((uint32_t *)(b->raw + b->curr));
b->curr += sizeof(uint32_t);
*o = ntohl(u);
return sizeof(uint32_t);
}
uint32_t sxtrdb_read_u64(sxtrdb_t *b, uint64_t *o)
{
uint64_t u;
if(!b || !o) return 0;
if(!b->raw) return 0;
if(b->curr >= b->ulength) return 0;
if(b->curr + sizeof(uint64_t) > b->ulength) return 0;
u = *((uint64_t *)(b->raw + b->curr));
b->curr += sizeof(uint64_t);
*o = ntohll(u);
return sizeof(uint64_t);
}
/* get raw data, pointer must be allocated with at least required length,
* will return size of ridden data
*/
uint32_t sxtrdb_read_raw(sxtrdb_t *b, void *o, uint32_t rlen)
{
if(!b || !o) return 0;
if(!rlen || !b->raw) return 0;
if(b->curr >= b->ulength) return 0;
if(b->curr + rlen > b->ulength) return 0;
memcpy(o, (const void*)b->raw + b->curr, rlen);
b->curr += rlen;
return rlen;
}
static int __rdb_grow(sxtrdb_t *b, uint32_t len)
{
uint32_t rlen;
char *ne = NULL;
if(!len) return -1;
if(b->rlength + len > SXTBUF_MAXLENGTH) return -1;
rlen = len +
(len%DEFAULT_PREALLOC_SIZE != 0 ? (DEFAULT_PREALLOC_SIZE - len%DEFAULT_PREALLOC_SIZE) : 0);
if(b->rlength + rlen > SXTBUF_MAXLENGTH) rlen = len;
rlen += b->rlength;
if(!(ne = malloc(rlen))) return -1;
if(b->flags & SXTRDB_BURN) memset(ne, 0, rlen);
memcpy(ne, b->raw, b->ulength);
if(b->flags & SXTRDB_BURN) memset(b->raw, 0, b->rlength);
free(b->raw);
b->raw = ne;
b->rlength = rlen;
return 0;
}
/* write different types, should return the size of the
* written data, otherwise error occurs */
uint32_t sxtrdb_write_u8(sxtrdb_t *b, uint8_t u)
{
if(!b || !b->raw) return 0;
if(b->ulength == b->rlength) {
if(__rdb_grow(b, sizeof(uint8_t))) return 0;
}
*(uint8_t *)(b->raw + b->ulength) = u;
b->ulength += sizeof(uint8_t);
return sizeof(uint8_t);
}
uint32_t sxtrdb_write_u16(sxtrdb_t *b, uint16_t uu)
{
if(!b || !b->raw) return 0;
if(b->ulength + sizeof(uint16_t) >= b->rlength) {
if(__rdb_grow(b, sizeof(uint16_t))) return 0;
}
*(uint16_t *)(b->raw + b->ulength) = htons(uu);
b->ulength += sizeof(uint16_t);
return sizeof(uint16_t);
}
uint32_t sxtrdb_write_u32(sxtrdb_t *b, uint32_t uu)
{
if(!b || !b->raw) return 0;
if(b->ulength + sizeof(uint32_t) >= b->rlength) {
if(__rdb_grow(b, sizeof(uint32_t))) return 0;
}
*(uint32_t *)(b->raw + b->ulength) = htonl(uu);
b->ulength += sizeof(uint32_t);
return sizeof(uint32_t);
}
uint32_t sxtrdb_write_u64(sxtrdb_t *b, uint64_t uu)
{
if(!b || !b->raw) return 0;
if(b->ulength + sizeof(uint64_t) >= b->rlength) {
if(__rdb_grow(b, sizeof(uint64_t))) return 0;
}
*(uint64_t *)(b->raw + b->ulength) = ntohll(uu);
b->ulength += sizeof(uint64_t);
return sizeof(uint64_t);
}
/* write raw data with the given length */
uint32_t sxtrdb_write_raw(sxtrdb_t *b, void *wi, uint32_t len)
{
if(!b || !b->raw) return 0;
if(!wi || !len) return 0;
if(b->ulength + len >= b->rlength) {
if(__rdb_grow(b, len)) return 0;
}
memcpy((void *)b->raw + b->ulength, (const void *)wi, len);
b->ulength += len;
return len;
}
/* write raw data *before* existing data */
uint32_t sxtrdb_write_raw_head(sxtrdb_t *b, void *wi, uint32_t len)
{
char *ne;
uint32_t rlen;
if(!b || !b->raw) return 0;
if(!wi || !len) return 0;
if(b->ulength + len > b->rlength) {
/* allocate a new one and copy it right */
if(b->rlength + len > SXTBUF_MAXLENGTH) return -1;
rlen = len +
(len%DEFAULT_PREALLOC_SIZE != 0 ? (DEFAULT_PREALLOC_SIZE - len%DEFAULT_PREALLOC_SIZE) : 0);
if(b->rlength + rlen > SXTBUF_MAXLENGTH) rlen = len;
rlen += b->rlength;
if(!(ne = malloc(rlen))) return -1;
if(b->flags & SXTRDB_BURN) memset(ne, 0, rlen);
memcpy((void *)ne + len, b->raw, b->ulength);
if(b->flags & SXTRDB_BURN) memset(b->raw, 0, b->rlength);
free(b->raw);
b->raw = ne;
b->rlength = rlen;
} else {
memmove((void *)b->raw + b->ulength, b->raw, b->ulength);
}
memcpy(b->raw, wi, len);
b->ulength += len;
return len;
}
/* parse */
int sxtrdb_escan_va(sxtrdb_t *b, const char *fmt, int argc, va_list ap)
{
va_list ap_copy;
union {
uint8_t *_u8;
uint16_t *_u16;
uint32_t *_u32;
uint64_t *_u64;
void **_dp;
char **_cstr;
sxtrdb_t **_rdb;
} d;
const char *t, *last;
uint32_t len, clen;
int r, count;
va_copy(ap_copy, ap);
for(t = fmt, count = 0; *t != '\0'; t++, count++) {
if(count > argc && argc != -1) {
va_end(ap_copy);
return SXT_EINVAL;
}
switch(*t) {
case 'b':
d._u8 = va_arg(ap, uint8_t *);
len = sxtrdb_read_u8(b, d._u8);
r = (len == sizeof(uint8_t)) ? SXT_SUCCESS : SXT_ERDBRD;
break;
case 'w':
d._u16 = va_arg(ap, uint16_t *);
len = sxtrdb_read_u16(b, d._u16);
r = (len == sizeof(uint16_t)) ? SXT_SUCCESS : SXT_ERDBRD;
break;
case 'd':
d._u32 = va_arg(ap, uint32_t *);
len = sxtrdb_read_u32(b, d._u32);
r = (len == sizeof(uint32_t)) ? SXT_SUCCESS : SXT_ERDBRD;
break;
case 'q':
d._u64 = va_arg(ap, uint64_t *);
len = sxtrdb_read_u64(b, d._u64);
r = (len == sizeof(uint64_t)) ? SXT_SUCCESS : SXT_ERDBRD;
break;
case 's':
d._cstr = va_arg(ap, char **);
*d._cstr = NULL;
len = sxtrdb_read_u32(b, &clen);
if(len != sizeof(uint32_t)) {
__errrbread:
r = SXT_ERDBRD;
break;
}
if(clen > SXTBUF_MAXLENGTH) goto __errrbread;
if((*d._cstr = malloc(clen + sizeof(char))) == NULL) {
r = SXT_ENOMEM;
break;
}
len = sxtrdb_read_raw(b, *d._cstr, clen);
if(len != clen) {
free(*d._cstr);
goto __errrbread;
}
(*d._cstr)[len] = '\0';
d._cstr = NULL;
r = SXT_SUCCESS;
break;
case 'p':
clen = va_arg(ap, size_t);
d._dp = va_arg(ap, void **);
*d._dp = NULL;
count++;
if((*d._dp = malloc(clen)) == NULL) {
r = SXT_ENOMEM;
break;
}
len = sxtrdb_read_raw(b, *d._dp, clen);
if(len != clen) {
free(*d._dp);
goto __errrbread;
}
d._dp = NULL;
r = SXT_SUCCESS;
break;
case 'P':
d._dp = va_arg(ap, void **);
*d._dp = NULL;
len = sxtrdb_read_u32(b, &clen);
if(len != sizeof(uint32_t)) {
r = SXT_ERDBRD;
break;
}
if((*d._dp = malloc(clen)) == NULL) {
r = SXT_ENOMEM;
break;
}
len = sxtrdb_read_raw(b, *d._dp, clen);
if(len != clen) {
free(*d._dp);
goto __errrbread;
}
d._dp = NULL;
r = SXT_SUCCESS;
break;
case 'R':
d._rdb = va_arg(ap, sxtrdb_t **);
*d._rdb = NULL;
len = sxtrdb_read_u32(b, &clen);
if(len != sizeof(uint32_t)) {
r = SXT_ERDBRD;
break;
}
/* allocate rdb and write to it */
if((*d._rdb = sxtrdb_new_palloc(clen)) == NULL) {
r = SXT_ENOMEM;
break;
} else sxtrdb_setflags(*d._rdb, SXTRDB_BURN);
len = sxtrdb_read_raw(b, sxtrdb_rdata(*d._rdb), clen);
if(len != clen) {
sxtrdb_free(*d._dp);
goto __errrbread;
} else sxtrdb_setlength(*d._rdb, clen);
d._rdb = NULL;
r = SXT_SUCCESS;
break;
}
if(r != SXT_SUCCESS) break;
}
if(argc != -1 && argc != count) r = SXT_EINVAL;
if(r == SXT_SUCCESS) {
clen = va_arg(ap, uint32_t);
if(clen != SXTRDB_TERMINAT) {
if(argc == -1) r = SXT_EINVAL;
else abort();
}
}
/* clean up all the stuff on error */
if(r != SXT_SUCCESS) {
last = t;
for(t = fmt; t < last; ++t) {
switch(*t) {
case 'b':
case 'w':
case 'd':
case 'q':
(void)va_arg(ap_copy, void *);
break;
case 's':
d._cstr = va_arg(ap_copy, char **);
if(*d._cstr) {
memset(*d._cstr, 0, strlen(*d._cstr));
free(*d._cstr);
}
break;
case 'R':
d._rdb = va_arg(ap_copy, sxtrdb_t **);
if(*d._rdb) sxtrdb_free(*d._rdb);
break;
case 'p':
(void)va_arg(ap_copy, size_t);
case 'P':
d._dp = va_arg(ap_copy, void **);
if(*d._dp) free(*d._dp);
break;
default:
(void)va_arg(ap_copy, void *);
break;
}
}
}
va_end(ap_copy);
return r;
}
int sxtrdb_escan_wot(sxtrdb_t *b, const char *fmt, int argc, ...)
{
va_list ap;
int r;
va_start(ap, argc);
r = sxtrdb_escan_va(b, fmt, argc, ap);
va_end(ap);
return r;
}
/* print FIXME: TODO: add errno setting upon failure */
uint32_t sxtrdb_print_va(sxtrdb_t *b, const char *fmt, int argc, va_list ap)
{
const char *t;
char *cstr;
sxtrdb_t *rdb;
union {
uint8_t _u8;
uint16_t _u16;
uint32_t _u32;
uint64_t _u64;
void *_dp;
} d;
uint32_t len = 0, clen;
int r, count;
for(t = fmt, count = 0; *t != '\0'; t++, count++) {
if(count > argc && argc != -1) return 0;
switch(*t) {
case 'b':
d._u8 = (uint8_t)va_arg(ap, unsigned int);
r = sxtrdb_write_u8(b, d._u8);
if(r != sizeof(uint8_t)) return 0;
else len += r;
break;
case 'w':
d._u16 = (uint16_t)va_arg(ap, unsigned int);
r = sxtrdb_write_u16(b, d._u16);
if(r != sizeof(uint16_t)) return 0;
else len += r;
break;
case 'd':
d._u32 = (uint32_t)va_arg(ap, uint32_t);
r = sxtrdb_write_u32(b, d._u32);
if(r != sizeof(uint32_t)) return 0;
else len += r;
break;
case 'q':
d._u64 = (uint64_t)va_arg(ap, uint64_t);
r = sxtrdb_write_u64(b, d._u64);
if(r != sizeof(uint64_t)) return 0;
else len += r;
break;
case 's':
cstr = (char *)va_arg(ap, char *);
clen = strlen(cstr);
r = sxtrdb_write_u32(b, (uint32_t)clen);
if(r != sizeof(uint32_t)) return 0;
else len += r;
r = sxtrdb_write_raw(b, cstr, clen);
if(r != clen) return 0;
else len += clen;
break;
case 'R':
rdb = (sxtrdb_t *)va_arg(ap, sxtrdb_t *);
clen = sxtrdb_length(rdb);
r = sxtrdb_write_u32(b, (uint32_t)clen);
if(r != sizeof(uint32_t)) return 0;
else len += r;
r = sxtrdb_write_raw(b, sxtrdb_rdata(rdb), (uint32_t)clen);
if(r != clen) return 0;
else len += clen;
break;
case 'P':
clen = va_arg(ap, size_t);
d._dp = va_arg(ap, void *);
count++;
r = sxtrdb_write_u32(b, (uint32_t)clen);
if(r != sizeof(uint32_t)) return 0;
else len += r;
r = sxtrdb_write_raw(b, d._dp, (uint32_t)clen);
if(r != clen) return 0;
else len += clen;
break;
case 'p':
clen = va_arg(ap, size_t);
d._dp = va_arg(ap, void *);
count++;
r = sxtrdb_write_raw(b, d._dp, (uint32_t)clen);
if(r != clen) return 0;
else len += clen;
break;
default:
return 0;
break;
}
}
if(argc != count && argc != -1) return 0;
clen = va_arg(ap, uint32_t);
if(clen != SXTRDB_TERMINAT) {
if(argc == -1) return 0;
else abort(); /* corruption */
}
return len;
}
uint32_t sxtrdb_print_wot(sxtrdb_t *b, const char *fmt, int argc, ...)
{
va_list ap;
uint32_t wrl;
va_start(ap, argc);
wrl = sxtrdb_print_va(b, fmt, argc, ap);
va_end(ap);
return wrl;
}
/* misc */
/* returns length of used space in the buffer */
uint32_t sxtrdb_length(sxtrdb_t *b)
{
if(!b || !b->raw) return 0;
return b->ulength;
}
/* returns length of allocated space in the buffer */
uint32_t sxtrdb_alength(sxtrdb_t *b)
{
if(!b || !b->raw) return 0;
return b->rlength;
}
/* returns length of the left data to read */
uint32_t sxtrdb_leftlength(sxtrdb_t *b)
{
if(!b || !b->raw) return 0;
if(b->curr > b->ulength) return 0;
return b->ulength - b->curr;
}
/* reaturn a pointer to the raw data */
void *sxtrdb_rdata(sxtrdb_t *b)
{
if(!b || !b->raw) return NULL;
return (void *)b->raw;
}
/* return pointer to the data currently being read/write */
void *sxtrdb_rdatacur(sxtrdb_t *b)
{
if(!b || !b->raw) return NULL;
if(b->curr >= b->ulength) return NULL;
return (void *)(b->raw + b->curr);
}
/* reset current pointer */
void sxtrdb_resetcur(sxtrdb_t *b)
{
if(!b || b->raw) return;
else b->curr = 0;
return;
}
/* set flags to the raw buffer */
void sxtrdb_setflags(sxtrdb_t *b, int af)
{
if(!b) return;
b->flags |= af;
return;
}
/* exchange flags for raw buff */
void sxtrdb_exflags(sxtrdb_t *b, int nf)
{
if(!b) return;
b->flags = nf;
return;
}
int sxtrdb_setlength(sxtrdb_t *b, uint32_t s)
{
if(!b) return SXT_EINVAL;
if(s > b->rlength) return SXT_EINVAL;
else b->ulength = s;
return SXT_SUCCESS;
}
/* compare buffers, returns 0 if equal */
int sxtrdb_cmp(sxtrdb_t *b1, sxtrdb_t *b2)
{
int c = 0;
if(!b1 | !b2) return -1;
if((c = sxtrdb_length(b1) - sxtrdb_length(b2)) != 0) return c;
else c = memcmp((const void *)sxtrdb_rdata(b1),
(const void *)sxtrdb_rdata(b2),
sxtrdb_length(b1));
return c;
}
/* let the buffer to use actually used bytes, not all allocated space
* will return SXT_SUCCESS on success (or in case if it doesn't required),
* SXT_ENOMEM or other error if fails
*/
int sxtrdb_memopt(sxtrdb_t *b)
{
uint32_t len;
char *ne;
if(!b || !b->raw) return SXT_EINVAL;
if((b->rlength - b->ulength) > DEFAULT_PREALLOC_SIZE) {
len = b->ulength +
(b->ulength%DEFAULT_PREALLOC_SIZE != 0 ?
(DEFAULT_PREALLOC_SIZE - b->ulength%DEFAULT_PREALLOC_SIZE) : 0);
if(!(ne = malloc(len))) return SXT_ENOMEM;
if(b->flags & SXTRDB_BURN) memset(ne, 0, len);
memcpy(ne, b->raw, b->ulength);
if(b->flags & SXTRDB_BURN) memset(b->raw, 0, b->ulength);
free(b->raw);
b->raw = ne;
b->rlength = len;
}
return SXT_SUCCESS;
}
#undef DEFAULT_PREALLOC_SIZE

@ -37,7 +37,7 @@
#include <sxt/errno.h>
#include <sxt/safebuf.h>
#include <sxt/rdb.h>
#include <ndbuf/ndbuf.h>
#include <sxt/sxtkey.h>
#include <sxt/socket.h>
#include <sxt/sxt.h>

@ -37,7 +37,7 @@
#include <sxt/errno.h>
#include <sxt/safebuf.h>
#include <sxt/rdb.h>
#include <ndbuf/ndbuf.h>
#include <sxt/sxtkey.h>
#include <sxt/socket.h>
#include <sxt/sxt.h>

@ -37,7 +37,7 @@
#include <sxt/errno.h>
#include <sxt/safebuf.h>
#include <sxt/rdb.h>
#include <ndbuf/ndbuf.h>
#include <sxt/sxtkey.h>
#include <sxt/socket.h>
#include <sxt/sxt.h>

Loading…
Cancel
Save