pull/11/head
parent
37a1506b18
commit
6a416795b7
@ -0,0 +1,11 @@
|
||||
// converts src[0:slen] to base64 string
|
||||
char *base64_to(char *dst,const u8 *src,size_t slen);
|
||||
// calculates length needed to store data converted to base64
|
||||
#define BASE64_TO_LEN(l) (((l + 3 - 1) / 3) * 4)
|
||||
// converts src string from base64
|
||||
size_t base64_from(u8 *dst,const char *src,size_t slen);
|
||||
// calculates length needed to store data converted from base
|
||||
#define BASE64_FROM_LEN(l) ((l) / 4 * 3)
|
||||
// validates base32 string and optionally stores length of valid data
|
||||
// returns 1 if whole string is good, 0 if string contains invalid data
|
||||
int base64_valid(const char *src,size_t *count);
|
@ -0,0 +1,90 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include "types.h"
|
||||
#include "base64.h"
|
||||
|
||||
static const u8 base64f[256] = {
|
||||
//00 01 02 03 04 05 06 07
|
||||
//08 09 0A 0B 0C 0D 0E 0F
|
||||
// 0x00..0x3F
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x00
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x08
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x10
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x18
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x20
|
||||
0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xFF, 0xFF, 0x3F, // 0x28
|
||||
0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, // 0x30
|
||||
0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x38
|
||||
// 0x40..0x7F
|
||||
0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // 0x40
|
||||
0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, // 0x48
|
||||
0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, // 0x50
|
||||
0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x58
|
||||
0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, // 0x60
|
||||
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, // 0x68
|
||||
0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, // 0x70
|
||||
0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x78
|
||||
// 0x80..0xBF
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
// 0xC0..0xFF
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
};
|
||||
|
||||
size_t base64_from(u8 *dst,const char *src,size_t srclen)
|
||||
{
|
||||
if (srclen % 4) {
|
||||
return -1;
|
||||
} else if (!srclen) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t dstlen = BASE64_FROM_LEN(srclen);
|
||||
dstlen -= (src[srclen - 1] == '=');
|
||||
dstlen -= (src[srclen - 2] == '=');
|
||||
|
||||
for (size_t i = 0, j = 0; i < srclen;) {
|
||||
u32 sixbits[4];
|
||||
|
||||
sixbits[0] = base64f[(unsigned char)src[i++]];
|
||||
sixbits[1] = base64f[(unsigned char)src[i++]];
|
||||
sixbits[2] = (src[i] == '=' ? (0 & i++) : base64f[(unsigned char)src[i++]]);
|
||||
sixbits[3] = (src[i] == '=' ? (0 & i++) : base64f[(unsigned char)src[i++]]);
|
||||
|
||||
u32 threebytes = 0
|
||||
| (sixbits[0] << (3 * 6))
|
||||
| (sixbits[1] << (2 * 6))
|
||||
| (sixbits[2] << (1 * 6))
|
||||
| (sixbits[3] << (0 * 6));
|
||||
|
||||
if (j < dstlen) dst[j++] = (threebytes >> (2 * 8));
|
||||
if (j < dstlen) dst[j++] = (threebytes >> (1 * 8)) & 0xff;
|
||||
if (j < dstlen) dst[j++] = (threebytes >> (0 * 8)) & 0xff;
|
||||
}
|
||||
return dstlen;
|
||||
}
|
||||
|
||||
int base64_valid(const char *src,size_t *count)
|
||||
{
|
||||
const char *p;
|
||||
|
||||
for (p = src;base64f[(u8)*p] != 0xFF;++p)
|
||||
;
|
||||
|
||||
if (count)
|
||||
*count = (size_t) (p - src);
|
||||
return !*p;
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include "types.h"
|
||||
#include "base64.h"
|
||||
|
||||
static const char base64t[64] = {
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
|
||||
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
|
||||
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
|
||||
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
|
||||
'w', 'x', 'y', 'z', '0', '1', '2', '3',
|
||||
'4', '5', '6', '7', '8', '9', '+', '/',
|
||||
};
|
||||
|
||||
char *base64_to(char *dst,const u8 *src,size_t slen)
|
||||
{
|
||||
if (!slen) {
|
||||
*dst = '\0';
|
||||
return dst;
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < slen;) {
|
||||
u32 threebytes = 0;
|
||||
threebytes |= (i < slen ? (unsigned char)src[i++] : (unsigned char)0) << (2 * 8);
|
||||
threebytes |= (i < slen ? (unsigned char)src[i++] : (unsigned char)0) << (1 * 8);
|
||||
threebytes |= (i < slen ? (unsigned char)src[i++] : (unsigned char)0) << (0 * 8);
|
||||
|
||||
*dst++ = base64t[(threebytes >> (3 * 6)) & 63];
|
||||
*dst++ = base64t[(threebytes >> (2 * 6)) & 63];
|
||||
*dst++ = base64t[(threebytes >> (1 * 6)) & 63];
|
||||
*dst++ = base64t[(threebytes >> (0 * 6)) & 63];
|
||||
}
|
||||
|
||||
switch (slen % 3) {
|
||||
case 0 : break;
|
||||
case 1 : {
|
||||
*(dst-2) = '=';
|
||||
*(dst-1) = '=';
|
||||
break;
|
||||
}
|
||||
case 2 : {
|
||||
*(dst-1) = '=';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*dst = '\0';
|
||||
return dst;
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
|
||||
#define LINEFEED_LEN (sizeof(char))
|
||||
#define NULLTERM_LEN (sizeof(char))
|
||||
#define PATH_SEPARATOR_LEN (sizeof(char))
|
||||
|
||||
static const int use_secret_mode = 1;
|
||||
static const int use_public_mode = 0;
|
||||
|
||||
static const char hostname_filename[] = "hostname";
|
||||
static const char secret_key_filename[] = "hs_ed25519_secret_key";
|
||||
static const char public_key_filename[] = "hs_ed25519_public_key";
|
||||
|
||||
static const char keys_field_generated[] = "generated:";
|
||||
static const char keys_field_hostname[] = " - hostname: ";
|
||||
static const char keys_field_secretkey[] = " - hs_ed25519_secret_key: ";
|
||||
static const char keys_field_publickey[] = " - hs_ed25519_public_key: ";
|
||||
static const char keys_field_time[] = " - time: ";
|
||||
|
||||
#define KEYS_FIELD_GENERATED_LEN (sizeof(keys_field_generated) - NULLTERM_LEN)
|
||||
#define KEYS_FIELD_HOSTNAME_LEN (sizeof(keys_field_hostname) - NULLTERM_LEN)
|
||||
#define KEYS_FIELD_SECRETKEY_LEN (sizeof(keys_field_secretkey) - NULLTERM_LEN)
|
||||
#define KEYS_FIELD_PUBLICKEY_LEN (sizeof(keys_field_publickey) - NULLTERM_LEN)
|
||||
#define KEYS_FIELD_TIME_LEN (sizeof(keys_field_time) - NULLTERM_LEN)
|
||||
|
||||
static const char hostname_example[] = "xxxxxvsjzke274nisktdqcl3eqm5ve3m6iur6vwme7m5p6kxivrvjnyd.onion";
|
||||
static const char seckey_example[] = "PT0gZWQyNTUxOXYxLXNlY3JldDogdHlwZTAgPT0AAACwCPMr6rvBRtkW7ZzZ8P7Ne4acRZrhPrN/EF6AETRraFGvdrkW5es4WXB2UxrbuUf8zPoIKkXK5cpdakYdUeM3";
|
||||
static const char pubkey_example[] = "PT0gZWQyNTUxOXYxLXB1YmxpYzogdHlwZTAgPT0AAAC973vWScqJr/GokqY4CXskGdqTbPIpH1bMJ9nX+VdFYw==";
|
||||
static const char time_example[] = "2018-07-04 21:31:20";
|
||||
|
||||
#define HOSTNAME_LEN (sizeof(hostname_example) - NULLTERM_LEN)
|
||||
#define SECKEY_LEN (sizeof(seckey_example) - NULLTERM_LEN)
|
||||
#define PUBKEY_LEN (sizeof(pubkey_example) - NULLTERM_LEN)
|
||||
#define TIME_LEN (sizeof(time_example) - NULLTERM_LEN)
|
||||
|
||||
#define KEYS_LEN ( KEYS_FIELD_GENERATED_LEN + LINEFEED_LEN \
|
||||
+ KEYS_FIELD_HOSTNAME_LEN + HOSTNAME_LEN + LINEFEED_LEN \
|
||||
+ KEYS_FIELD_SECRETKEY_LEN + SECKEY_LEN + LINEFEED_LEN \
|
||||
+ KEYS_FIELD_PUBLICKEY_LEN + PUBKEY_LEN + LINEFEED_LEN \
|
||||
+ KEYS_FIELD_TIME_LEN + TIME_LEN + LINEFEED_LEN \
|
||||
+ LINEFEED_LEN \
|
||||
)
|
@ -0,0 +1,44 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include "types.h"
|
||||
#include "base64.h"
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <sodium/randombytes.h>
|
||||
|
||||
struct texttestcase {
|
||||
const char *in;
|
||||
const char *out;
|
||||
const char *rev;
|
||||
} tests0[] = {
|
||||
{"", "", ""},
|
||||
{"f", "Zg==", "f"},
|
||||
{"fo", "Zm8=", "fo"},
|
||||
{"foo", "Zm9v", "foo"},
|
||||
{"foob", "Zm9vYg==", "foob"},
|
||||
{"fooba", "Zm9vYmE=", "fooba"},
|
||||
{"foobar", "Zm9vYmFy", "foobar"},
|
||||
};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
char buf[1024], buf2[1024];
|
||||
size_t r;
|
||||
for (size_t i = 0; i < sizeof(tests0)/sizeof(tests0[0]); ++i) {
|
||||
base64_to(buf, (const u8 *)tests0[i].in, strlen(tests0[i].in));
|
||||
if (strcmp(buf, tests0[i].out) != 0) {
|
||||
printf("invalid encoding result: \"%s\" -> encoded as \"%s\", but expected \"%s\".\n",
|
||||
tests0[i].in, buf, tests0[i].out);
|
||||
return 1;
|
||||
}
|
||||
r = base64_from((u8 *)buf2, buf, strlen(buf));
|
||||
buf2[r] = '\0';
|
||||
if (strcmp(buf2, tests0[i].rev) != 0) {
|
||||
printf("invalid decoding result: encoded \"%s\", decoded as \"%s\", but expected \"%s\".\n",
|
||||
tests0[i].out, buf2, tests0[i].rev);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
Loading…
Reference in new issue