|
|
@ -48,6 +48,10 @@
|
|
|
|
#include <sxt/ciphers.h>
|
|
|
|
#include <sxt/ciphers.h>
|
|
|
|
#include <sxt/base64.h>
|
|
|
|
#include <sxt/base64.h>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
|
|
|
#define blub(a) printf("%s:%d -> %d\n", __FUNCTION__, __LINE__, (a))
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
/* locals */
|
|
|
|
/* locals */
|
|
|
|
static int sxtkey_export_priv_ed25519(const sxtkey_t *key, const char *pass, sxtsafebuffer_t **bin);
|
|
|
|
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_2sb(const sxtkey_t *key, sxtsafebuffer_t **buf);
|
|
|
@ -103,6 +107,7 @@ sxtkey_t *sxtkey_alloc(void)
|
|
|
|
sxtkey_t *key = malloc(sizeof(sxtkey_t));
|
|
|
|
sxtkey_t *key = malloc(sizeof(sxtkey_t));
|
|
|
|
|
|
|
|
|
|
|
|
if(!key) return NULL;
|
|
|
|
if(!key) return NULL;
|
|
|
|
|
|
|
|
else memset(key, 0, sizeof(sxtkey_t));
|
|
|
|
|
|
|
|
|
|
|
|
return key;
|
|
|
|
return key;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -183,10 +188,10 @@ int sxtkey_assign_hash(sxtkey_t *key, uint64_t hash)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if(!key) return SXT_EINVAL;
|
|
|
|
if(!key) return SXT_EINVAL;
|
|
|
|
|
|
|
|
|
|
|
|
if(!sxtkey_private(key)) return SXT_EINVAL;
|
|
|
|
// if(!sxtkey_private(key)) return SXT_EINVAL;
|
|
|
|
|
|
|
|
|
|
|
|
if(key->hash) return SXT_EKEY;
|
|
|
|
//if(key->hash) return SXT_EKEY;
|
|
|
|
else key->hash = hash;
|
|
|
|
key->hash = hash;
|
|
|
|
|
|
|
|
|
|
|
|
return SXT_SUCCESS;
|
|
|
|
return SXT_SUCCESS;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -332,7 +337,7 @@ int sxtkey_import_priv_file(const char *file, const char *passkey,
|
|
|
|
char *rawfbuf = NULL, *tbuf, *tebuf, *tuple = NULL, *b64pk = NULL;
|
|
|
|
char *rawfbuf = NULL, *tbuf, *tebuf, *tuple = NULL, *b64pk = NULL;
|
|
|
|
struct stat stbuf;
|
|
|
|
struct stat stbuf;
|
|
|
|
uint8_t keytype = 0;
|
|
|
|
uint8_t keytype = 0;
|
|
|
|
int r = SXT_SUCCESS, tc = 0, tcc = 0, len;
|
|
|
|
int r = SXT_SUCCESS, tcc = 0, len;
|
|
|
|
|
|
|
|
|
|
|
|
*ik = NULL;
|
|
|
|
*ik = NULL;
|
|
|
|
|
|
|
|
|
|
|
@ -345,9 +350,9 @@ int sxtkey_import_priv_file(const char *file, const char *passkey,
|
|
|
|
if((stream = fopen(file, "r")) == NULL) return SXT_EIO;
|
|
|
|
if((stream = fopen(file, "r")) == NULL) return SXT_EIO;
|
|
|
|
|
|
|
|
|
|
|
|
if(!(rawfbuf = malloc(stbuf.st_size + sizeof(char)))) goto __failed;
|
|
|
|
if(!(rawfbuf = malloc(stbuf.st_size + sizeof(char)))) goto __failed;
|
|
|
|
else rawfbuf[stbuf.st_size + sizeof(char)] = '\0';
|
|
|
|
else rawfbuf[stbuf.st_size] = '\0';
|
|
|
|
|
|
|
|
|
|
|
|
if(fread(rawfbuf, stbuf.st_size + sizeof(char), 1, stream) != 1) {
|
|
|
|
if(fread(rawfbuf, stbuf.st_size, 1, stream) != 1) {
|
|
|
|
r = SXT_EIO;
|
|
|
|
r = SXT_EIO;
|
|
|
|
goto __failed;
|
|
|
|
goto __failed;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -357,7 +362,7 @@ int sxtkey_import_priv_file(const char *file, const char *passkey,
|
|
|
|
if(r != SXT_SUCCESS) goto __failed;
|
|
|
|
if(r != SXT_SUCCESS) goto __failed;
|
|
|
|
|
|
|
|
|
|
|
|
/* now we need to get a keytype and decode b64blob */
|
|
|
|
/* now we need to get a keytype and decode b64blob */
|
|
|
|
for(tbuf = rawfbuf, tc = 0, tcc = 0, tebuf = NULL; *tbuf != '\0'; tbuf++) {
|
|
|
|
for(tbuf = rawfbuf, tcc = 0, tebuf = NULL; *tbuf != '\0'; tbuf++) {
|
|
|
|
switch(tcc) {
|
|
|
|
switch(tcc) {
|
|
|
|
case 0: /* just entering */
|
|
|
|
case 0: /* just entering */
|
|
|
|
if(*tbuf == '(') tcc++;
|
|
|
|
if(*tbuf == '(') tcc++;
|
|
|
@ -365,7 +370,6 @@ int sxtkey_import_priv_file(const char *file, const char *passkey,
|
|
|
|
case 1: /* first e.g. key type plain text description */
|
|
|
|
case 1: /* first e.g. key type plain text description */
|
|
|
|
if(!tebuf) tebuf = tbuf;
|
|
|
|
if(!tebuf) tebuf = tbuf;
|
|
|
|
else if(tebuf && *tbuf == ' ') {
|
|
|
|
else if(tebuf && *tbuf == ' ') {
|
|
|
|
if(!tebuf) goto __failed;
|
|
|
|
|
|
|
|
len = (tbuf - tebuf) + sizeof(char);
|
|
|
|
len = (tbuf - tebuf) + sizeof(char);
|
|
|
|
if(!(tuple = malloc(len))) {
|
|
|
|
if(!(tuple = malloc(len))) {
|
|
|
|
r = SXT_ENOMEM;
|
|
|
|
r = SXT_ENOMEM;
|
|
|
@ -388,14 +392,13 @@ int sxtkey_import_priv_file(const char *file, const char *passkey,
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
case 2: /* private key contents */
|
|
|
|
case 2: /* private key contents */
|
|
|
|
if(!tebuf && *tbuf != ' ') tebuf = tbuf;
|
|
|
|
if(!tebuf && *tbuf != ' ') tebuf = tbuf;
|
|
|
|
else if(tebuf && *tbuf == ' ') {
|
|
|
|
else if(tebuf && *tbuf == '"') {
|
|
|
|
len = (tbuf - tebuf) + sizeof(char);
|
|
|
|
|
|
|
|
/* check format */
|
|
|
|
|
|
|
|
if(*tebuf != '"') tc = SXT_EKEYFMT;
|
|
|
|
|
|
|
|
if(!tc && tebuf[len - 2] != '"') tc = SXT_EKEYFMT;
|
|
|
|
|
|
|
|
len -= 2;
|
|
|
|
|
|
|
|
if(tc || len <= 0) { r = tc; goto __failed; }
|
|
|
|
|
|
|
|
tebuf++;
|
|
|
|
tebuf++;
|
|
|
|
|
|
|
|
len = (tbuf - tebuf) + sizeof(char);
|
|
|
|
|
|
|
|
if(len <= 1) {
|
|
|
|
|
|
|
|
r = SXT_EKEYFMT;
|
|
|
|
|
|
|
|
goto __failed;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(!(tuple = malloc(len))) { r = SXT_ENOMEM; goto __failed; }
|
|
|
|
if(!(tuple = malloc(len))) { r = SXT_ENOMEM; goto __failed; }
|
|
|
|
else memset(tuple, 0, len);
|
|
|
|
else memset(tuple, 0, len);
|
|
|
@ -418,7 +421,8 @@ int sxtkey_import_priv_file(const char *file, const char *passkey,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(tcc < 3) {
|
|
|
|
if(tcc < 3) {
|
|
|
|
r = SXT_EKEYFMT; goto __failed;
|
|
|
|
r = SXT_EKEYFMT;
|
|
|
|
|
|
|
|
goto __failed;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
r = sxtkey_privkey_import_fbase64blob(b64pk, keytype, ask_passkey, priv, ik);
|
|
|
|
r = sxtkey_privkey_import_fbase64blob(b64pk, keytype, ask_passkey, priv, ik);
|
|
|
@ -443,15 +447,15 @@ int sxtkey_privkey_import_rdbuf(sxtrdb_t *buf, uint8_t keytype,
|
|
|
|
sxtkey_t *key = NULL;
|
|
|
|
sxtkey_t *key = NULL;
|
|
|
|
char *keyname = NULL, *ciphername = NULL, *kdfname = NULL, *magic = NULL;
|
|
|
|
char *keyname = NULL, *ciphername = NULL, *kdfname = NULL, *magic = NULL;
|
|
|
|
uint64_t hash = 0;
|
|
|
|
uint64_t hash = 0;
|
|
|
|
uint32_t r1 = 0, r2 = 0;
|
|
|
|
uint32_t r1 = 0, r2 = 0, ctrl_pklen = 0;
|
|
|
|
int r = SXT_SUCCESS, decrypt = 0;
|
|
|
|
int r = SXT_SUCCESS, decrypt = 0;
|
|
|
|
|
|
|
|
|
|
|
|
if(!buf) return SXT_EINVAL;
|
|
|
|
if(!buf) return SXT_EINVAL;
|
|
|
|
if(!sxtrdb_length(buf)) return SXT_EINVAL;
|
|
|
|
if(!sxtrdb_length(buf)) return SXT_EINVAL;
|
|
|
|
if(keytype == 0) return SXT_EKEY;
|
|
|
|
if(keytype == 0) return SXT_EKEY;
|
|
|
|
|
|
|
|
|
|
|
|
r = sxtrdb_escan(buf, "sbsssRRR", &magic, &flags, &keyname, &ciphername, &kdfname,
|
|
|
|
r = sxtrdb_escan(buf, "sbsssRdRR", &magic, &flags, &keyname, &ciphername, &kdfname,
|
|
|
|
&kdfopt, &ctrl_pubkey, &privkey);
|
|
|
|
&kdfopt, &ctrl_pklen, &ctrl_pubkey, &privkey);
|
|
|
|
if(r != SXT_SUCCESS) goto __failed;
|
|
|
|
if(r != SXT_SUCCESS) goto __failed;
|
|
|
|
|
|
|
|
|
|
|
|
if(strcmp(PPKP_MAGIC, magic)) { /* magic should be right */
|
|
|
|
if(strcmp(PPKP_MAGIC, magic)) { /* magic should be right */
|
|
|
@ -471,6 +475,11 @@ int sxtkey_privkey_import_rdbuf(sxtrdb_t *buf, uint8_t keytype,
|
|
|
|
|
|
|
|
|
|
|
|
switch(keytype) {
|
|
|
|
switch(keytype) {
|
|
|
|
case PPKP_ED25519:
|
|
|
|
case PPKP_ED25519:
|
|
|
|
|
|
|
|
/* check public key length first */
|
|
|
|
|
|
|
|
if(ctrl_pklen != ED25519_PK_LEN + sizeof(uint32_t)) {
|
|
|
|
|
|
|
|
r = SXT_EKEY;
|
|
|
|
|
|
|
|
goto __failed;
|
|
|
|
|
|
|
|
}
|
|
|
|
/* check for encryption details */
|
|
|
|
/* check for encryption details */
|
|
|
|
if(decrypt) {
|
|
|
|
if(decrypt) {
|
|
|
|
if(strcmp(ciphername, "aes128-cbc") || strcmp(kdfname, "bcrypt")) {
|
|
|
|
if(strcmp(ciphername, "aes128-cbc") || strcmp(kdfname, "bcrypt")) {
|
|
|
@ -506,9 +515,10 @@ int sxtkey_privkey_import_rdbuf(sxtrdb_t *buf, uint8_t keytype,
|
|
|
|
goto __failed;
|
|
|
|
goto __failed;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* control check for random numbers */
|
|
|
|
/* control check for random numbers */
|
|
|
|
if(r1 != r2) goto __invalid;
|
|
|
|
if(r1 != r2) goto __invalid;
|
|
|
|
|
|
|
|
|
|
|
|
/* control check of public keys */
|
|
|
|
/* control check of public keys */
|
|
|
|
if(sxtrdb_cmp(ctrl_pubkey, ed25519_privbuf)) {
|
|
|
|
if(sxtrdb_cmp(ctrl_pubkey, ed25519_pubbuf)) {
|
|
|
|
__invalid:
|
|
|
|
__invalid:
|
|
|
|
sxtrdb_free(ed25519_pubbuf);
|
|
|
|
sxtrdb_free(ed25519_pubbuf);
|
|
|
|
sxtrdb_free(ed25519_privbuf);
|
|
|
|
sxtrdb_free(ed25519_privbuf);
|
|
|
@ -619,6 +629,7 @@ int sxtkey_pubkey_import_fbase64blob(const char *b64b, uint8_t keytype,
|
|
|
|
sxtrdb_t *keybuf = NULL;
|
|
|
|
sxtrdb_t *keybuf = NULL;
|
|
|
|
char *blob = NULL, *ed25519pk = NULL;
|
|
|
|
char *blob = NULL, *ed25519pk = NULL;
|
|
|
|
uint64_t hash;
|
|
|
|
uint64_t hash;
|
|
|
|
|
|
|
|
uint32_t klen = 0;
|
|
|
|
int len, r = SXT_SUCCESS;
|
|
|
|
int len, r = SXT_SUCCESS;
|
|
|
|
|
|
|
|
|
|
|
|
if(!b64b) return SXT_EINVAL;
|
|
|
|
if(!b64b) return SXT_EINVAL;
|
|
|
@ -643,7 +654,13 @@ int sxtkey_pubkey_import_fbase64blob(const char *b64b, uint8_t keytype,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* <pubkey><hash> */
|
|
|
|
/* <pubkey><hash> */
|
|
|
|
sxtrdb_write_raw(keybuf, blob, len);
|
|
|
|
sxtrdb_write_raw(keybuf, blob, len);
|
|
|
|
sxtrdb_escan(keybuf, "pq", ED25519_PK_LEN, ed25519pk, &hash);
|
|
|
|
sxtrdb_resetcur(keybuf);
|
|
|
|
|
|
|
|
sxtrdb_escan(keybuf, "dpq", &klen, ED25519_PK_LEN, ed25519pk, &hash);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(klen != ED25519_PK_LEN) {
|
|
|
|
|
|
|
|
r = SXT_EKEY;
|
|
|
|
|
|
|
|
goto __failed;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(hash != ctrl_hash) {
|
|
|
|
if(hash != ctrl_hash) {
|
|
|
|
r = SXT_EKEY;
|
|
|
|
r = SXT_EKEY;
|
|
|
@ -699,9 +716,9 @@ int sxtkey_import_public_file(const char *file, sxtkey_t **ik)
|
|
|
|
if((stream = fopen(file, "r")) == NULL) return SXT_EIO;
|
|
|
|
if((stream = fopen(file, "r")) == NULL) return SXT_EIO;
|
|
|
|
|
|
|
|
|
|
|
|
if(!(rawfbuf = malloc(stbuf.st_size + sizeof(char)))) goto __failed;
|
|
|
|
if(!(rawfbuf = malloc(stbuf.st_size + sizeof(char)))) goto __failed;
|
|
|
|
else rawfbuf[stbuf.st_size + sizeof(char)] = '\0';
|
|
|
|
else rawfbuf[stbuf.st_size] = '\0';
|
|
|
|
|
|
|
|
|
|
|
|
if(fread(rawfbuf, stbuf.st_size + sizeof(char), 1, stream) != 1) {
|
|
|
|
if(fread(rawfbuf, stbuf.st_size, 1, stream) != 1) {
|
|
|
|
r = SXT_EIO;
|
|
|
|
r = SXT_EIO;
|
|
|
|
goto __failed;
|
|
|
|
goto __failed;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -807,7 +824,7 @@ int sxtkey_import_public_file(const char *file, sxtkey_t **ik)
|
|
|
|
free(tuple);
|
|
|
|
free(tuple);
|
|
|
|
r = SXT_ENOMEM; goto __failed;
|
|
|
|
r = SXT_ENOMEM; goto __failed;
|
|
|
|
} else memset(tebuf, 0, len);
|
|
|
|
} else memset(tebuf, 0, len);
|
|
|
|
len = sxt_b64decode_in(tuple, len, tebuf, len);
|
|
|
|
len = sxt_b64decode_in(tuple, strlen(tuple), tebuf, len);
|
|
|
|
|
|
|
|
|
|
|
|
free(tuple);
|
|
|
|
free(tuple);
|
|
|
|
if(!(chbuf = sxtrdb_new())) {
|
|
|
|
if(!(chbuf = sxtrdb_new())) {
|
|
|
@ -815,6 +832,7 @@ int sxtkey_import_public_file(const char *file, sxtkey_t **ik)
|
|
|
|
r = SXT_ENOMEM; goto __failed;
|
|
|
|
r = SXT_ENOMEM; goto __failed;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
sxtrdb_write_raw(chbuf, tebuf, len);
|
|
|
|
sxtrdb_write_raw(chbuf, tebuf, len);
|
|
|
|
|
|
|
|
sxtrdb_resetcur(chbuf);
|
|
|
|
sxtrdb_read_u64(chbuf, &ctrl_hash);
|
|
|
|
sxtrdb_read_u64(chbuf, &ctrl_hash);
|
|
|
|
sxtrdb_free(chbuf);
|
|
|
|
sxtrdb_free(chbuf);
|
|
|
|
free(tebuf);
|
|
|
|
free(tebuf);
|
|
|
|