Remove dependency on base64c. Use libsodium's. Also consolidate the calls, as the usage is quite special.

git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4175 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
Cory McWilliams 2023-02-14 03:15:24 +00:00
parent fa87462405
commit 1f77df7a90
26 changed files with 43 additions and 771 deletions

View File

@ -76,11 +76,6 @@ $(APP_OBJS): CFLAGS += \
-Ideps/xopt \
-Werror
BASE64C_SOURCES := deps/base64c/src/base64c.c
BASE64C_OBJS := $(call get_objs,BASE64C_SOURCES)
$(BASE64C_OBJS): CFLAGS += \
-Wno-sign-compare
BLOWFISH_SOURCES := \
deps/crypt_blowfish/crypt_blowfish.c \
deps/crypt_blowfish/crypt_gensalt.c \
@ -207,6 +202,7 @@ SODIUM_SOURCES := \
deps/libsodium/src/libsodium/randombytes/randombytes.c \
deps/libsodium/src/libsodium/randombytes/sysrandom/randombytes_sysrandom.c \
deps/libsodium/src/libsodium/sodium/core.c \
deps/libsodium/src/libsodium/sodium/codecs.c \
deps/libsodium/src/libsodium/sodium/runtime.c \
deps/libsodium/src/libsodium/sodium/utils.c
SODIUM_OBJS := $(call get_objs,SODIUM_SOURCES)
@ -330,7 +326,6 @@ all: $(BUILD_TYPES)
ALL_APP_OBJS := \
$(APP_OBJS) \
$(BASE64C_OBJS) \
$(BLOWFISH_OBJS) \
$(LIBBACKTRACE_OBJS) \
$(PICOHTTPPARSER_OBJS) \

View File

@ -1,106 +0,0 @@
# Prerequisites
*.d
# Object files
*.o
*.ko
*.obj
*.elf
# Linker output
*.ilk
*.map
*.exp
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
# Debug files
*.dSYM/
*.su
*.idb
*.pdb
# Kernel Module Compile Results
*.mod*
*.cmd
.tmp_versions/
modules.order
Module.symvers
Mkfile.old
dkms.conf
# http://www.gnu.org/software/automake
Makefile
Makefile.in
/ar-lib
/mdate-sh
/py-compile
/test-driver
/ylwrap
# http://www.gnu.org/software/autoheader
config.h
# http://www.gnu.org/software/autoconf
autom4te.cache
/autoscan.log
/autoscan-*.log
/aclocal.m4
/compile
/config.guess
/config.h.in
/config.log
/config.status
/config.sub
/configure
/configure.scan
/depcomp
/install-sh
/missing
/stamp-h1
# https://www.gnu.org/software/libtool/
/ltmain.sh
# http://www.gnu.org/software/texinfo
/texinfo.tex
# http://www.gnu.org/software/m4/
m4/libtool.m4
m4/ltoptions.m4
m4/ltsugar.m4
m4/ltversion.m4
m4/lt~obsolete.m4
# vim
*.swp
# project specific
test/gen
test/test[0-9]*
test/.deps

29
deps/base64c/LICENSE vendored
View File

@ -1,29 +0,0 @@
BSD 3-Clause License
Copyright (c) 2018, Sean Hanna
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -1,2 +0,0 @@
AUTOMAKE_OPTIONS = foreign
SUBDIRS = src test

View File

@ -1,60 +0,0 @@
# base64c
This is primarily just a fork of a base64 decoder from the FreeBSD codebase. It has received a few modifications:
* removed all allocations, you are expected to pass in a buffer that has sufficient space and you will get an error (-1) if you run out of space
* replaced a dynamically generated lookup table with a hardcoded lookup table
* wrote my own unit tests, i'm sure there are tests for freebsd somewhere but i didn't find them
# Embedding
This code is primarily intended to be dropped into an existing code base ( or perhaps using submodules). To do that:
* grab include/base64c.h
* grab src/base64c.h
# Usage
Call base64c_encoding_length() to calculate how big a buffer you need to encode a string. It's somewhere around 4 times the size of the input string. This length includes a null terminator.
```c
char input_string[256];
size_t new_len = base64c_encoding_length( strlen(input_string));
unsigned char *buffer = (unsigned char*)malloc(new_len);
```
Call base64c_encode() to actually encode your input string as base64. It will write to the buffer and return how many characters were written. If there was an error it will return -1.
```c
size_t output_length = base64c_encode(input_string, strlen(input_string), buffer, new_len);
if (output_length == -1) {
int x = 1/0; // ERROR!
}
```
Call base64c_decoding_length() to calculate how big a buffer you need to decode. It comes out to about half the size. This number isn't always exact, but it is close to within a byte or two.
```c
size_t decode_len = base64c_decoding_length( strlen(buffer) );
unsigned char *decoded = (unsigned char*)malloc( decode_len );
```
Call base64c_decode() to decode an encoded base64 string. It will write to the buffer and return how many characters were written. IF there was an error it will return -1. If the string contains invalid number of characters, or has any characters that are not part of the base64 character set an error will be returned.
# Building
You need to bootstrap all the autoconf tools by running ./autogen.sh
You need to have autoconf installed to do this.
Once bootstrapped run ./configure
# Tests
There are tests in the test/ subfolder. They will be built automatically. There is no special test runner. You can run each of the test cases manually to check whether the code is working properly.
# References
(http://web.mit.edu/freebsd/head/contrib/wpa/src/utils/base64.c)
(https://github.com/freebsd/freebsd/blob/master/contrib/wpa/src/utils/base64.c)

View File

@ -1,3 +0,0 @@
#!/bin/sh
aclocal && automake --gnu --add-missing && autoconf

View File

@ -1,22 +0,0 @@
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
BASE64C_VERSION=0.5
AC_PREREQ([2.69])
AC_INIT(base64c, 0.5, hannasm@gmail.com)
AM_INIT_AUTOMAKE(base64c, 0.5)
AC_CONFIG_SRCDIR([include/base64c.h])
AC_CONFIG_HEADERS([config.h])
# Checks for programs.
AC_PROG_CC
# Checks for libraries.
# Checks for header files.
# Checks for typedefs, structures, and compiler characteristics.
AC_TYPE_SIZE_T
# Checks for library functions.
AC_OUTPUT(Makefile src/Makefile test/Makefile)

View File

@ -1,42 +0,0 @@
#ifndef base64cC_H
#define base64cC_H
#include <stddef.h>
#include <stdint.h>
/**
* base64c_encoding_length - calculate length to allocate for encode
* @len: Length of input string
* Returns: number of bytes required to base64c encode, this includes room for '\0' terminator
*/
size_t base64c_encoding_length(size_t len);
/**
* base64c_decoding_length - calculate length to allocate for decode
* @len: Length of (base64 encoded) input string
* Returns: maximum number of bytes required to decode
*/
size_t base64c_decoding_length(size_t inlen);
/**
* base64c_encode - base64c encode
* @src: Data to be encoded
* @len: Length of the data to be encoded
* @out: Mutable output buffer destination, all encoded bytes will be written to the destination
* @out_len: length of output buffer
* Returns: number of bytes written, or -1 if there was an error
*/
size_t base64c_encode(const unsigned char *src, size_t len, unsigned char* out, const size_t out_len);
/**
* base64c_decode - base64c decode
* @src: Data to be decoded
* @len: Length of the data to be decoded
* @out_len: Pointer to output length variable
* Returns: Allocated buffer of out_len bytes of decoded data,
* or %NULL on failure
*
* Caller is responsible for freeing the returned buffer.
*/
size_t base64c_decode(const unsigned char *src, size_t len, unsigned char *out, const size_t out_len);
#endif

View File

@ -1,3 +0,0 @@
CFLAGS = --pednatic -Wall -stdc99 -O2
LDFLAGS =

View File

@ -1,139 +0,0 @@
#include <string.h>
#include <stdio.h>
/*
* Base64 encoding/decoding (RFC1341)
* Copyright (c) 2005-2011, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
static const unsigned char base64c_table[65] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static const unsigned char base64c_dtable[256] = {
/*000*/0x80,/*001*/0x80,/*002*/0x80,/*003*/0x80,/*004*/0x80,/*005*/0x80,/*006*/0x80,/*007*/0x80,/*008*/0x80,/*009*/0x80,/*010*/0x80,/*011*/0x80,/*012*/0x80,/*013*/0x80,/*014*/0x80,/*015*/0x80,/*016*/0x80,/*017*/0x80,/*018*/0x80,/*019*/0x80,
/*020*/0x80,/*021*/0x80,/*022*/0x80,/*023*/0x80,/*024*/0x80,/*025*/0x80,/*026*/0x80,/*027*/0x80,/*028*/0x80,/*029*/0x80,/*030*/0x80,/*031*/0x80,/*032*/0x80,/*033*/0x80,/*034*/0x80,/*035*/0x80,/*036*/0x80,/*037*/0x80,/*038*/0x80,/*039*/0x80,
/*040*/0x80,/*041*/0x80,/*042*/0x80,/*043*/0x3e,/*044*/0x80,/*045*/0x80,/*046*/0x80,/*047*/0x3f,/*048*/0x34,/*049*/0x35,/*050*/0x36,/*051*/0x37,/*052*/0x38,/*053*/0x39,/*054*/0x3a,/*055*/0x3b,/*056*/0x3c,/*057*/0x3d,/*058*/0x80,/*059*/0x80,
/*060*/0x80,/*061*/0x00,/*062*/0x80,/*063*/0x80,/*064*/0x80,/*065*/0x00,/*066*/0x01,/*067*/0x02,/*068*/0x03,/*069*/0x04,/*070*/0x05,/*071*/0x06,/*072*/0x07,/*073*/0x08,/*074*/0x09,/*075*/0x0a,/*076*/0x0b,/*077*/0x0c,/*078*/0x0d,/*079*/0x0e,
/*080*/0x0f,/*081*/0x10,/*082*/0x11,/*083*/0x12,/*084*/0x13,/*085*/0x14,/*086*/0x15,/*087*/0x16,/*088*/0x17,/*089*/0x18,/*090*/0x19,/*091*/0x80,/*092*/0x80,/*093*/0x80,/*094*/0x80,/*095*/0x80,/*096*/0x80,/*097*/0x1a,/*098*/0x1b,/*099*/0x1c,
/*100*/0x1d,/*101*/0x1e,/*102*/0x1f,/*103*/0x20,/*104*/0x21,/*105*/0x22,/*106*/0x23,/*107*/0x24,/*108*/0x25,/*109*/0x26,/*110*/0x27,/*111*/0x28,/*112*/0x29,/*113*/0x2a,/*114*/0x2b,/*115*/0x2c,/*116*/0x2d,/*117*/0x2e,/*118*/0x2f,/*119*/0x30,
/*120*/0x31,/*121*/0x32,/*122*/0x33,/*123*/0x80,/*124*/0x80,/*125*/0x80,/*126*/0x80,/*127*/0x80,/*128*/0x80,/*129*/0x80,/*130*/0x80,/*131*/0x80,/*132*/0x80,/*133*/0x80,/*134*/0x80,/*135*/0x80,/*136*/0x80,/*137*/0x80,/*138*/0x80,/*139*/0x80,
/*140*/0x80,/*141*/0x80,/*142*/0x80,/*143*/0x80,/*144*/0x80,/*145*/0x80,/*146*/0x80,/*147*/0x80,/*148*/0x80,/*149*/0x80,/*150*/0x80,/*151*/0x80,/*152*/0x80,/*153*/0x80,/*154*/0x80,/*155*/0x80,/*156*/0x80,/*157*/0x80,/*158*/0x80,/*159*/0x80,
/*160*/0x80,/*161*/0x80,/*162*/0x80,/*163*/0x80,/*164*/0x80,/*165*/0x80,/*166*/0x80,/*167*/0x80,/*168*/0x80,/*169*/0x80,/*170*/0x80,/*171*/0x80,/*172*/0x80,/*173*/0x80,/*174*/0x80,/*175*/0x80,/*176*/0x80,/*177*/0x80,/*178*/0x80,/*179*/0x80,
/*180*/0x80,/*181*/0x80,/*182*/0x80,/*183*/0x80,/*184*/0x80,/*185*/0x80,/*186*/0x80,/*187*/0x80,/*188*/0x80,/*189*/0x80,/*190*/0x80,/*191*/0x80,/*192*/0x80,/*193*/0x80,/*194*/0x80,/*195*/0x80,/*196*/0x80,/*197*/0x80,/*198*/0x80,/*199*/0x80,
/*200*/0x80,/*201*/0x80,/*202*/0x80,/*203*/0x80,/*204*/0x80,/*205*/0x80,/*206*/0x80,/*207*/0x80,/*208*/0x80,/*209*/0x80,/*210*/0x80,/*211*/0x80,/*212*/0x80,/*213*/0x80,/*214*/0x80,/*215*/0x80,/*216*/0x80,/*217*/0x80,/*218*/0x80,/*219*/0x80,
/*220*/0x80,/*221*/0x80,/*222*/0x80,/*223*/0x80,/*224*/0x80,/*225*/0x80,/*226*/0x80,/*227*/0x80,/*228*/0x80,/*229*/0x80,/*230*/0x80,/*231*/0x80,/*232*/0x80,/*233*/0x80,/*234*/0x80,/*235*/0x80,/*236*/0x80,/*237*/0x80,/*238*/0x80,/*239*/0x80,
/*240*/0x80,/*241*/0x80,/*242*/0x80,/*243*/0x80,/*244*/0x80,/*245*/0x80,/*246*/0x80,/*247*/0x80,/*248*/0x80,/*249*/0x80,/*250*/0x80,/*251*/0x80,/*252*/0x80,/*253*/0x80,/*254*/0x80,/*255*/0x00,
};
size_t base64c_encoding_length(size_t len) {
size_t olen = len * 4 / 3 + 4; /* 3-byte blocks to 4-byte */
olen++; /* nul termination */
if (olen < len)
return 0; /* integer overflow */
return olen;
}
size_t base64c_encode(const unsigned char *src, size_t len,
unsigned char* out, const size_t out_len)
{
unsigned char *pos;
const unsigned char *end, *in;
const unsigned char *out_end = out + out_len;
end = src + len;
in = src;
pos = out;
if (out_len < base64c_encoding_length(len)) { return -1; }
while (end - in >= 3 ) {
*pos++ = base64c_table[in[0] >> 2];
*pos++ = base64c_table[((in[0] & 0x03) << 4) | (in[1] >> 4)];
*pos++ = base64c_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)];
*pos++ = base64c_table[in[2] & 0x3f];
in += 3;
}
if (end - in) {
*pos++ = base64c_table[in[0] >> 2];
if (end - in == 1) {
*pos++ = base64c_table[(in[0] & 0x03) << 4];
*pos++ = '=';
} else {
*pos++ = base64c_table[((in[0] & 0x03) << 4) | (in[1] >> 4)];
*pos++ = base64c_table[(in[1] & 0x0f) << 2];
}
*pos++ = '=';
}
*pos = '\0';
return out_len - (out_end-pos);
}
size_t base64c_decoding_length(size_t inlen) {
return inlen / 4 * 3;
}
size_t base64c_decode(const unsigned char *src, size_t len, unsigned char *out, const size_t out_len)
{
if (out == NULL) { return 0; }
if (out_len <= 0) { return 0; }
unsigned char *pos, block[4], tmp;
size_t i, count;
int pad = 0;
if (len == 0 ){
*out = '\0';
return 1;
}
if (len % 4) {
return -1;
}
pos = out;
count = 0;
for (i = 0; i < len; i++) {
if (src[i] == '=') { pad++; }
tmp = base64c_dtable[src[i]];
if (tmp == 0x80) { return -1; }
block[count] = tmp;
count++;
if (count == 4) {
switch (pad) {
case 0:
if ((pos - out) + 3 > out_len) {
return -1;
}
*pos++ = (block[0] << 2) | (block[1] >> 4);
*pos++ = (block[1] << 4) | (block[2] >> 2);
*pos++ = (block[2] << 6) | block[3];
break;
case 1:
if ((pos - out) + 2 > out_len || i + 1 > len) {
return -1;
}
*pos++ = (block[0] << 2) | (block[1] >> 4);
*pos++ = (block[1] << 4) | (block[2] >> 2);
break;
case 2:
if ((pos - out) + 1 > out_len || i + 1 > len) {
return -1;
}
*pos++ = (block[0] << 2) | (block[1] >> 4);
break;
default:
break;
}
count = 0;
}
}
return pos - out;
}

View File

@ -1,16 +0,0 @@
CFLAGS = --pedantic -Wall -std=c99 -g -ggdb
LDFLAGS =
bin_PROGRAMS = test001 test002 test003 test004 \
test005 test006 test007 test008 \
gen
test001_SOURCES = test001.c ../src/base64c.c
test002_SOURCES = test002.c ../src/base64c.c
test003_SOURCES = test003.c ../src/base64c.c
test004_SOURCES = test004.c ../src/base64c.c
test005_SOURCES = test005.c ../src/base64c.c
test006_SOURCES = test006.c ../src/base64c.c
test007_SOURCES = test007.c ../src/base64c.c
test008_SOURCES = test008.c ../src/base64c.c
gen_SOURCES = gen.c

View File

@ -1,22 +0,0 @@
#include <stdio.h>
#include <string.h>
static const unsigned char base64_table[65] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int main() {
unsigned char out[256];
memset(out, 0x80, 255);
for (int i = 0; i < 64; i++) {
out[base64_table[i]] = i;
}
out['='] = 0;
printf("static const unsigned char base64c_dtable[256] = {");
for (int i = 0; i < 256; i++) {
if (i% 20==0) { printf("\n"); }
printf("/*%03d*/0x%02x,", i, out[i]);
}
printf("\n};");
}

View File

@ -1,36 +0,0 @@
#include "../include/base64c.h"
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]) {
unsigned char in[12] = "Hello World";
size_t in_len = 11;
unsigned char enc[32];
size_t enc_len = 32;
unsigned char out[12];
size_t out_len = 12;
printf("Encoding %lu - %s\n", in_len, in);
size_t enc_result = base64c_encode(in, in_len, enc, enc_len);
printf("Encoded %lu - %s\n", enc_result, enc);
size_t dec_result = base64c_decode(enc, enc_result, out, out_len);
if ((long)dec_result < 0) {
printf("Decode failed with code %ld\n", (long)dec_result);
return 1;
}
printf("Decoded %lu - %s\n", dec_result, out);
if (dec_result != in_len) {
printf("in length %ld not equal to out length %ld", in_len, dec_result);
return 3;
}
if (strncmp((char*)in, (char*)out, in_len)) {
printf("roundtrip encoding failed\n");
return 2;
}
}

View File

@ -1,37 +0,0 @@
#include "../include/base64c.h"
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]) {
unsigned char in[11] = "Hello Worl";
size_t in_len = 10;
unsigned char enc[32];
size_t enc_len = 32;
unsigned char out[12];
size_t out_len = 12;
printf("Encoding %lu - %s\n", in_len, in);
size_t enc_result = base64c_encode(in, in_len, enc, enc_len);
printf("Encoded %lu - %s\n", enc_result, enc);
size_t dec_result = base64c_decode(enc, enc_result, out, out_len);
if ((long)dec_result < 0) {
printf("Decode failed with code %ld\n", (long)dec_result);
return 1;
}
printf("Decoded %lu - %s\n", dec_result, out);
if (dec_result != in_len) {
printf("in length %ld not equal to out length %ld", in_len, dec_result);
return 3;
}
if (strncmp((char*)in, (char*)out, in_len)) {
printf("roundtrip encoding failed\n");
return 2;
}
}

View File

@ -1,37 +0,0 @@
#include "../include/base64c.h"
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]) {
unsigned char in[10] = "Hello Wor";
size_t in_len = 9;
unsigned char enc[32];
size_t enc_len = 32;
unsigned char out[12];
size_t out_len = 12;
printf("Encoding %lu - %s\n", in_len, in);
size_t enc_result = base64c_encode(in, in_len, enc, enc_len);
printf("Encoded %lu - %s\n", enc_result, enc);
size_t dec_result = base64c_decode(enc, enc_result, out, out_len);
if ((long)dec_result < 0) {
printf("Decode failed with code %ld\n", (long)dec_result);
return 1;
}
printf("Decoded %lu - %s\n", dec_result, out);
if (dec_result != in_len) {
printf("in length %ld not equal to out length %ld", in_len, dec_result);
return 3;
}
if (strncmp((char*)in, (char*)out, in_len)) {
printf("roundtrip encoding failed\n");
return 2;
}
}

View File

@ -1,37 +0,0 @@
#include "../include/base64c.h"
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]) {
unsigned char in[10] = "Hello Wo";
size_t in_len = 8;
unsigned char enc[32];
size_t enc_len = 32;
unsigned char out[12];
size_t out_len = 12;
printf("Encoding %lu - %s\n", in_len, in);
size_t enc_result = base64c_encode(in, in_len, enc, enc_len);
printf("Encoded %lu - %s\n", enc_result, enc);
size_t dec_result = base64c_decode(enc, enc_result, out, out_len);
if ((long)dec_result < 0) {
printf("Decode failed with code %ld\n", (long)dec_result);
return 1;
}
printf("Decoded %lu - %s\n", dec_result, out);
if (dec_result != in_len) {
printf("in length %ld not equal to out length %ld", in_len, dec_result);
return 3;
}
if (strncmp((char*)in, (char*)out, in_len)) {
printf("roundtrip encoding failed\n");
return 2;
}
}

View File

@ -1,36 +0,0 @@
#include "../include/base64c.h"
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]) {
unsigned char in[13] = "Hello Worlds";
size_t in_len = 12;
unsigned char enc[32];
size_t enc_len = 32;
unsigned char out[13];
size_t out_len = 13;
printf("Encoding %lu - %s\n", in_len, in);
size_t enc_result = base64c_encode(in, in_len, enc, enc_len);
printf("Encoded %lu - %s\n", enc_result, enc);
size_t dec_result = base64c_decode(enc, enc_result, out, out_len);
if ((long)dec_result < 0) {
printf("Decode failed with code %ld\n", (long)dec_result);
return 1;
}
printf("Decoded %lu - %s\n", dec_result, out);
if (dec_result != in_len) {
printf("in length %ld not equal to out length %ld", in_len, dec_result);
return 3;
}
if (strncmp((char*)in, (char*)out, in_len)) {
printf("roundtrip encoding failed\n");
return 2;
}
}

View File

@ -1,36 +0,0 @@
#include "../include/base64c.h"
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]) {
unsigned char in[14] = "Hello Worldsy";
size_t in_len = 13;
unsigned char enc[32];
size_t enc_len = 32;
unsigned char out[15];
size_t out_len = 15;
printf("Encoding %lu - %s\n", in_len, in);
size_t enc_result = base64c_encode(in, in_len, enc, enc_len);
printf("Encoded %lu - %s\n", enc_result, enc);
size_t dec_result = base64c_decode(enc, enc_result, out, out_len);
if ((long)dec_result < 0) {
printf("Decode failed with code %ld\n", (long)dec_result);
return 1;
}
printf("Decoded %lu - %s\n", dec_result, out);
if (dec_result != in_len) {
printf("in length %ld not equal to out length %ld", in_len, dec_result);
return 3;
}
if (strncmp((char*)in, (char*)out, in_len)) {
printf("roundtrip encoding failed\n");
return 2;
}
}

View File

@ -1,36 +0,0 @@
#include "../include/base64c.h"
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]) {
unsigned char in[15] = "Hello World of";
size_t in_len = 14;
unsigned char enc[32];
size_t enc_len = 32;
unsigned char out[15];
size_t out_len = 15;
printf("Encoding %lu - %s\n", in_len, in);
size_t enc_result = base64c_encode(in, in_len, enc, enc_len);
printf("Encoded %lu - %s\n", enc_result, enc);
size_t dec_result = base64c_decode(enc, enc_result, out, out_len);
if ((long)dec_result < 0) {
printf("Decode failed with code %ld\n", (long)dec_result);
return 1;
}
printf("Decoded %lu - %s\n", dec_result, out);
if (dec_result != in_len) {
printf("in length %ld not equal to out length %ld", in_len, dec_result);
return 3;
}
if (strncmp((char*)in, (char*)out, in_len)) {
printf("roundtrip encoding failed\n");
return 2;
}
}

View File

@ -1,37 +0,0 @@
#include "../include/base64c.h"
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]) {
unsigned char in[10] = "H";
size_t in_len = 1;
unsigned char enc[32];
size_t enc_len = 32;
unsigned char out[12];
size_t out_len = 12;
printf("Encoding %lu - %s\n", in_len, in);
size_t enc_result = base64c_encode(in, in_len, enc, enc_len);
printf("Encoded %lu - %s\n", enc_result, enc);
size_t dec_result = base64c_decode(enc, enc_result, out, out_len);
if ((long)dec_result < 0) {
printf("Decode failed with code %ld\n", (long)dec_result);
return 1;
}
printf("Decoded %lu - %s\n", dec_result, out);
if (dec_result != in_len) {
printf("in length %ld not equal to out length %ld", in_len, dec_result);
return 3;
}
if (strncmp((char*)in, (char*)out, in_len)) {
printf("roundtrip encoding failed\n");
return 2;
}
}

View File

@ -8,7 +8,6 @@
#include "util.js.h"
#include <assert.h>
#include <base64c.h>
#include <quickjs.h>
#include <sodium/crypto_auth.h>
#include <sodium/crypto_box.h>
@ -884,7 +883,7 @@ void tf_ssb_calculate_message_id(JSContext* context, JSValue message, char* out_
crypto_hash_sha256(id, (uint8_t*)latin1, latin1_len);
char id_base64[k_id_base64_len];
base64c_encode(id, sizeof(id), (uint8_t*)id_base64, sizeof(id_base64));
tf_base64_encode(id, sizeof(id), id_base64, sizeof(id_base64));
snprintf(out_id, out_id_size, "%%%s.sha256", id_base64);
@ -932,11 +931,11 @@ static bool _tf_ssb_verify_and_strip_signature_internal(JSContext* context, JSVa
const char* type = strstr(author_id, ".ed25519");
uint8_t publickey[crypto_box_PUBLICKEYBYTES];
int r = base64c_decode((const uint8_t*)author_id, type - author_id, publickey, sizeof(publickey));
int r = tf_base64_decode(author_id, type - author_id, publickey, sizeof(publickey));
if (r != -1)
{
uint8_t binsig[crypto_sign_BYTES];
r = base64c_decode((const uint8_t*)str, sigkind - str, binsig, sizeof(binsig));
r = tf_base64_decode(str, sigkind - str, binsig, sizeof(binsig));
if (r != -1)
{
r = crypto_sign_verify_detached(binsig, (const uint8_t*)sigstr, strlen(sigstr), publickey);
@ -1028,7 +1027,7 @@ void tf_ssb_send_close(tf_ssb_t* ssb)
bool tf_ssb_id_bin_to_str(char* str, size_t str_size, const uint8_t* bin)
{
char buffer[k_id_base64_len - 9];
base64c_encode(bin, crypto_sign_PUBLICKEYBYTES, (uint8_t*)buffer, sizeof(buffer));
tf_base64_encode(bin, crypto_sign_PUBLICKEYBYTES, buffer, sizeof(buffer));
return snprintf(str, str_size, "@%s.ed25519", buffer) < (int)str_size;
}
@ -1036,7 +1035,7 @@ bool tf_ssb_id_str_to_bin(uint8_t* bin, const char* str)
{
const char* author_id = str && *str == '@' ? str + 1 : str;
const char* type = strstr(str, ".ed25519");
return base64c_decode((const uint8_t*)author_id, type - author_id, bin, crypto_box_PUBLICKEYBYTES) != 0;
return tf_base64_decode(author_id, type - author_id, bin, crypto_box_PUBLICKEYBYTES) != 0;
}
static void _tf_ssb_notify_connections_changed(tf_ssb_t* ssb, tf_ssb_change_t change, tf_ssb_connection_t* connection)
@ -1685,7 +1684,7 @@ void tf_ssb_append_message_with_keys(tf_ssb_t* ssb, const char* author, const ui
JS_FreeValue(context, jsonval);
char signature_base64[crypto_sign_BYTES * 2];
base64c_encode(signature, sizeof(signature), (uint8_t*)signature_base64, sizeof(signature_base64));
tf_base64_encode(signature, sizeof(signature), signature_base64, sizeof(signature_base64));
strcat(signature_base64, ".sig.ed25519");
JSValue sigstr = JS_NewString(context, signature_base64);
JS_SetPropertyStr(context, root, "signature", sigstr);
@ -2170,11 +2169,11 @@ void tf_ssb_generate_keys_buffer(char* out_public, size_t public_size, char* out
uint8_t private[crypto_sign_SECRETKEYBYTES];
crypto_sign_ed25519_keypair(public, private);
uint8_t buffer[512];
base64c_encode(public, sizeof(public), buffer, sizeof(buffer));
char buffer[512];
tf_base64_encode(public, sizeof(public), buffer, sizeof(buffer));
snprintf(out_public, public_size, "%s.ed25519", buffer);
base64c_encode(private, sizeof(private), buffer, sizeof(buffer));
tf_base64_encode(private, sizeof(private), buffer, sizeof(buffer));
snprintf(out_private, private_size, "%s.ed25519", buffer);
}
@ -2601,7 +2600,7 @@ static void _tf_ssb_send_broadcast(tf_ssb_t* ssb, struct sockaddr_in* address)
}
char fullid[k_id_base64_len];
base64c_encode(ssb->pub, sizeof(ssb->pub), (uint8_t*)fullid, sizeof(fullid));
tf_base64_encode(ssb->pub, sizeof(ssb->pub), fullid, sizeof(fullid));
char message[512];
snprintf(message, sizeof(message), "net:%s:%d~shs:%s", address_str, ntohs(((struct sockaddr_in*)&server_addr)->sin_port), fullid);
@ -2700,7 +2699,7 @@ static bool _tf_ssb_parse_broadcast(const char* in_broadcast, tf_ssb_broadcast_t
{
out_broadcast->addr.sin_family = AF_INET;
out_broadcast->addr.sin_port = htons((uint16_t)port);
int r = base64c_decode((const uint8_t*)public_key_str, strlen(public_key_str), out_broadcast->pub, crypto_sign_PUBLICKEYBYTES);
int r = tf_base64_decode(public_key_str, strlen(public_key_str), out_broadcast->pub, crypto_sign_PUBLICKEYBYTES);
return r != -1;
}
else if (strncmp(in_broadcast, "ws:", 3) == 0)

View File

@ -5,7 +5,6 @@
#include "trace.h"
#include "util.js.h"
#include <base64c.h>
#include <sodium/crypto_hash_sha256.h>
#include <sodium/crypto_scalarmult.h>
#include <sodium/crypto_scalarmult_curve25519.h>
@ -434,7 +433,7 @@ bool tf_ssb_db_blob_store(tf_ssb_t* ssb, const uint8_t* blob, size_t size, char*
crypto_hash_sha256(hash, blob, size);
char hash64[256];
base64c_encode(hash, sizeof(hash), (uint8_t*)hash64, sizeof(hash64));
tf_base64_encode(hash, sizeof(hash), hash64, sizeof(hash64));
char id[512];
snprintf(id, sizeof(id), "&%s.sha256", hash64);
@ -965,8 +964,8 @@ bool tf_ssb_db_identity_get_private_key(tf_ssb_t* ssb, const char* user, const c
{
if (sqlite3_step(statement) == SQLITE_ROW)
{
const uint8_t* key = sqlite3_column_text(statement, 0);
int r = base64c_decode(key, sqlite3_column_bytes(statement, 0) - strlen(".ed25519"), out_private_key, private_key_size);
const char* key = (const char*)sqlite3_column_text(statement, 0);
int r = tf_base64_decode(key, sqlite3_column_bytes(statement, 0) - strlen(".ed25519"), out_private_key, private_key_size);
success = r > 0;
}
}
@ -1140,7 +1139,7 @@ static void _test_private(sqlite3* db, const uint8_t* private_key)
while (sqlite3_step(statement) == SQLITE_ROW)
{
uint8_t buffer[8192];
int r = base64c_decode(sqlite3_column_text(statement, 0) + 1, sqlite3_column_bytes(statement, 0) - strlen("\".box\""), buffer, sizeof(buffer));
int r = tf_base64_decode((const char*)sqlite3_column_text(statement, 0) + 1, sqlite3_column_bytes(statement, 0) - strlen("\".box\""), buffer, sizeof(buffer));
if (r > 1)
{
@ -1195,7 +1194,7 @@ void tf_ssb_db_private(sqlite3* db)
{
uint8_t private_key[crypto_sign_SECRETKEYBYTES] = { 0 };
printf("-> %s\n", sqlite3_column_text(statement, 0));
int r = base64c_decode(sqlite3_column_text(statement, 1), sqlite3_column_bytes(statement, 1) - strlen(".ed25519"), private_key, sizeof(private_key));
int r = tf_base64_decode((const char*)sqlite3_column_text(statement, 1), sqlite3_column_bytes(statement, 1) - strlen(".ed25519"), private_key, sizeof(private_key));
if (r == sizeof(private_key))
{
uint8_t key[crypto_sign_SECRETKEYBYTES] = { 0 };

View File

@ -6,7 +6,6 @@
#include "ssb.h"
#include "util.js.h"
#include <base64c.h>
#include <sodium/crypto_hash_sha256.h>
#include <sodium/crypto_sign.h>
#include <string.h>
@ -960,7 +959,7 @@ static JSValue _tf_ssb_hmacsha256_sign(JSContext* context, JSValueConst this_val
if (crypto_sign_detached(signature, &siglen, (const uint8_t*)payload, payload_length, private_key) == 0)
{
char signature_base64[crypto_sign_BYTES * 2];
base64c_encode(signature, sizeof(signature), (uint8_t*)signature_base64, sizeof(signature_base64));
tf_base64_encode(signature, sizeof(signature), signature_base64, sizeof(signature_base64));
result = JS_NewString(context, signature_base64);
}
}
@ -995,10 +994,10 @@ static JSValue _tf_ssb_hmacsha256_verify(JSContext* context, JSValueConst this_v
}
uint8_t bin_public_key[crypto_sign_PUBLICKEYBYTES] = { 0 };
if (base64c_decode((const uint8_t*)public_key_start, public_key_end - public_key_start, bin_public_key, sizeof(bin_public_key)) > 0)
if (tf_base64_decode(public_key_start, public_key_end - public_key_start, bin_public_key, sizeof(bin_public_key)) > 0)
{
uint8_t bin_signature[crypto_sign_BYTES] = { 0 };
if (base64c_decode((const uint8_t*)signature, signature_length, bin_signature, sizeof(bin_signature)) > 0)
if (tf_base64_decode(signature, signature_length, bin_signature, sizeof(bin_signature)) > 0)
{
if (crypto_sign_verify_detached(bin_signature, (const uint8_t*)payload, payload_length, bin_public_key) == 0)
{

View File

@ -623,7 +623,9 @@ static void _test_b64(const tf_test_options_t* options)
fprintf(file,
"'use strict';\n"
"print(base64Encode('hello'));\n"
"if (base64Decode(base64Encode('hello')) !== 'hello') {\n"
"let x = base64Decode(base64Encode('hello'));\n"
"if (x !== 'hello') {\n"
" print(x);\n"
" exit(1);\n"
"}\n"
);

View File

@ -4,11 +4,11 @@
#include "task.h"
#include "trace.h"
#include <base64c.h>
#include <openssl/crypto.h>
#include <openssl/sha.h>
#include <picohttpparser.h>
#include <quickjs-libc.h>
#include <sodium/utils.h>
#include <uv.h>
#include <string.h>
@ -70,7 +70,7 @@ static JSValue _util_base64_encode(JSContext* context, JSValueConst this_val, in
if (array)
{
char* encoded = tf_malloc(length * 4);
int r = base64c_encode(array, length, (uint8_t*)encoded, length * 4);
int r = tf_base64_encode(array, length, encoded, length * 4);
if (r >= 0)
{
result = JS_NewStringLen(context, encoded, r);
@ -81,7 +81,7 @@ static JSValue _util_base64_encode(JSContext* context, JSValueConst this_val, in
{
const char* value = JS_ToCStringLen(context, &length, argv[0]);
char* encoded = tf_malloc(length * 4);
int r = base64c_encode((const uint8_t*)value, length, (uint8_t*)encoded, length * 4);
int r = tf_base64_encode((const uint8_t*)value, length, encoded, length * 4);
if (r >= 0)
{
result = JS_NewStringLen(context, encoded, r);
@ -97,12 +97,12 @@ static JSValue _util_base64_decode(JSContext* context, JSValueConst this_val, in
JSValue result = JS_UNDEFINED;
size_t length = 0;
const char* value = JS_ToCStringLen(context, &length, argv[0]);
char* encoded = tf_malloc(length);
uint8_t* encoded = tf_malloc(length);
int r = base64c_decode((const uint8_t*)value, length, (uint8_t*)encoded, length);
int r = tf_base64_decode(value, length, encoded, length);
if (r >= 0)
{
result = JS_NewStringLen(context, encoded, r);
result = JS_NewStringLen(context, (const char*)encoded, r);
}
tf_free(encoded);
@ -406,3 +406,14 @@ int tf_util_insert_index(const void* key, const void* base, size_t count, size_t
return lower;
}
size_t tf_base64_encode(const uint8_t* source, size_t source_length, char* out, size_t out_length)
{
sodium_bin2base64(out, out_length, source, source_length, sodium_base64_VARIANT_ORIGINAL);
return sodium_base64_ENCODED_LEN(source_length, sodium_base64_VARIANT_ORIGINAL) - 1;
}
size_t tf_base64_decode(const char* source, size_t source_length, uint8_t* out, size_t out_length)
{
size_t actual_length = 0;
return sodium_base642bin(out, out_length, source, source_length, NULL, &actual_length, NULL, sodium_base64_VARIANT_ORIGINAL) == 0 ? actual_length : 0;
}

View File

@ -12,3 +12,6 @@ bool tf_util_report_error(JSContext* context, JSValue value);
int tf_util_get_length(JSContext* context, JSValue value);
int tf_util_insert_index(const void* key, const void* base, size_t count, size_t size, int (*compare)(const void*, const void*));
JSValue tf_util_new_uint8_array(JSContext* context, const uint8_t* data, size_t size);
size_t tf_base64_encode(const uint8_t* source, size_t source_length, char* out, size_t out_length);
size_t tf_base64_decode(const char* source, size_t source_length, uint8_t* out, size_t out_length);