add lfcrypto, base64
This commit is contained in:
parent
624bd7a23b
commit
360fb91e06
@ -15,6 +15,7 @@ set(SOURCES
|
|||||||
src/string.c
|
src/string.c
|
||||||
src/vector.c
|
src/vector.c
|
||||||
src/utility.c
|
src/utility.c
|
||||||
|
src/crypto.c
|
||||||
)
|
)
|
||||||
|
|
||||||
if ((${CMAKE_SYSTEM_NAME} STREQUAL "Darwin"))
|
if ((${CMAKE_SYSTEM_NAME} STREQUAL "Darwin"))
|
||||||
|
24
docs/crypto.md
Normal file
24
docs/crypto.md
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# crypto
|
||||||
|
|
||||||
|
Cryptographic library
|
||||||
|
|
||||||
|
## Functions
|
||||||
|
|
||||||
|
### b64_encode
|
||||||
|
|
||||||
|
Encodes an `unsigned char *` into base64. User is responsible for freeing the
|
||||||
|
`char *` that is returned.
|
||||||
|
|
||||||
|
```c
|
||||||
|
char *b64_encode(const unsigned char *s, size_t sz);
|
||||||
|
```
|
||||||
|
|
||||||
|
### b64_decode
|
||||||
|
|
||||||
|
Decodes a base64 encoded set of bytes into an `unsigned char *`. User is responsible
|
||||||
|
for freeing the `unsigned char *` that is returned. `decode_sz` is an optional argument
|
||||||
|
in case you need to know the size of the decoded data, otherwise you can just pass `NULL`.
|
||||||
|
|
||||||
|
```c
|
||||||
|
unsigned char *b64_decode(const char *s, size_t sz, size_t *decode_sz);
|
||||||
|
```
|
9
include/lfcrypto.h
Normal file
9
include/lfcrypto.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#ifndef LIBFLINT_CRYPTO_H
|
||||||
|
#define LIBFLINT_CRYPTO_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
char *b64_encode(const unsigned char *s, size_t sz);
|
||||||
|
unsigned char *b64_decode(const char *s, size_t sz, size_t *decode_sz);
|
||||||
|
|
||||||
|
#endif // LIBFLINT_CRYPTO_H
|
@ -7,6 +7,7 @@ nav:
|
|||||||
- 'Modules':
|
- 'Modules':
|
||||||
- 'Binary Tree': 'binarytree.md'
|
- 'Binary Tree': 'binarytree.md'
|
||||||
- 'Boolean': 'bool.md'
|
- 'Boolean': 'bool.md'
|
||||||
|
- 'Crypto': 'crypto.md'
|
||||||
- 'Input': 'input.md'
|
- 'Input': 'input.md'
|
||||||
- 'Linked List': 'linkedlist.md'
|
- 'Linked List': 'linkedlist.md'
|
||||||
- 'Math': 'math.md'
|
- 'Math': 'math.md'
|
||||||
|
202
src/crypto.c
Normal file
202
src/crypto.c
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "lfcrypto.h"
|
||||||
|
|
||||||
|
#define B64_BUF_SZ (1024 * 64)
|
||||||
|
|
||||||
|
static const char b64_table[] = {
|
||||||
|
'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', '+', '/'
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *ptr;
|
||||||
|
int count;
|
||||||
|
} b64_buf;
|
||||||
|
|
||||||
|
static int new_b64_buf(b64_buf *b) {
|
||||||
|
b->ptr = malloc(B64_BUF_SZ);
|
||||||
|
if (b->ptr == NULL) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
b->count = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int resize_b64_buf(b64_buf *b, size_t sz) {
|
||||||
|
if (sz > b->count * B64_BUF_SZ) {
|
||||||
|
while (sz > b->count * B64_BUF_SZ) {
|
||||||
|
b->count++;
|
||||||
|
}
|
||||||
|
b->ptr = realloc(b->ptr, B64_BUF_SZ * b->count);
|
||||||
|
if (b->ptr == NULL) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *b64_encode(const unsigned char *s, size_t sz) {
|
||||||
|
int i = 0;
|
||||||
|
b64_buf encbuf;
|
||||||
|
size_t size = 0;
|
||||||
|
unsigned char buf[4];
|
||||||
|
unsigned char tmp[3];
|
||||||
|
|
||||||
|
if (new_b64_buf(&encbuf) != 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (sz--) {
|
||||||
|
tmp[i++] = *(s++);
|
||||||
|
if (i == 3) {
|
||||||
|
buf[0] = (tmp[0] & 0xfc) >> 2;
|
||||||
|
buf[1] = ((tmp[0] & 0x03) << 4) + ((tmp[1] & 0xf0) >> 4);
|
||||||
|
buf[2] = ((tmp[1] & 0x0f) << 2) + ((tmp[2] & 0xc0) >> 6);
|
||||||
|
buf[3] = tmp[2] & 0x3f;
|
||||||
|
|
||||||
|
if (resize_b64_buf(&encbuf, size + 4) != 0) {
|
||||||
|
free(encbuf.ptr);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 4; ++i) {
|
||||||
|
encbuf.ptr[size++] = b64_table[buf[i]];
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i > 0) {
|
||||||
|
for (int j = i; j < 3; ++j) {
|
||||||
|
tmp[j] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[0] = (tmp[0] & 0xfc) >> 2;
|
||||||
|
buf[1] = ((tmp[0] & 0x03) << 4) + ((tmp[1] & 0xf0) >> 4);
|
||||||
|
buf[2] = ((tmp[1] & 0x0f) << 2) + ((tmp[2] & 0xc0) >> 6);
|
||||||
|
buf[3] = tmp[2] & 0x3f;
|
||||||
|
|
||||||
|
for (int j = 0; (j < i + 1); ++j) {
|
||||||
|
if (resize_b64_buf(&encbuf, size + 1) != 0) {
|
||||||
|
free(encbuf.ptr);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
encbuf.ptr[size++] = b64_table[buf[j]];
|
||||||
|
}
|
||||||
|
|
||||||
|
while (i++ < 3) {
|
||||||
|
if (resize_b64_buf(&encbuf, size + 1) != 0) {
|
||||||
|
free(encbuf.ptr);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
encbuf.ptr[size++] = '=';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resize_b64_buf(&encbuf, size + 1) != 0) {
|
||||||
|
free(encbuf.ptr);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
encbuf.ptr[size] = '\0';
|
||||||
|
|
||||||
|
return encbuf.ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char *b64_decode(const char *s, size_t sz, size_t *decode_sz) {
|
||||||
|
int i = 0, j = 0, l = 0;
|
||||||
|
size_t size = 0;
|
||||||
|
b64_buf decbuf;
|
||||||
|
unsigned char buf[3];
|
||||||
|
unsigned char tmp[4];
|
||||||
|
|
||||||
|
if (new_b64_buf(&decbuf) != 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (sz--) {
|
||||||
|
if (s[j] == '=') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Not base64 characters
|
||||||
|
if (!isalnum(s[j]) || s[j] == '+' || s[j] == '/') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp[i++] = s[j++];
|
||||||
|
|
||||||
|
if (i == 4) {
|
||||||
|
for (i = 0; i < 4; ++i) {
|
||||||
|
for (l = 0; l < 64; ++l) {
|
||||||
|
if (tmp[i] == b64_table[l]) {
|
||||||
|
tmp[i] = l;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[0] = (tmp[0] << 2) + ((tmp[1] & 0x30) >> 4);
|
||||||
|
buf[1] = ((tmp[1] & 0xf) << 4) + ((tmp[2] & 0x3c) >> 2);
|
||||||
|
buf[2] = ((tmp[2] & 0x3) << 6) + tmp[3];
|
||||||
|
|
||||||
|
if (resize_b64_buf(&decbuf, size + 3) != 0) {
|
||||||
|
free(decbuf.ptr);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 3; ++i) {
|
||||||
|
decbuf.ptr[size++] = buf[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i > 0) {
|
||||||
|
for (j = i; j < 4; ++j) {
|
||||||
|
tmp[j] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 0; j < 4; ++j) {
|
||||||
|
for (l = 0; l < 64; ++l) {
|
||||||
|
if (tmp[j] == b64_table[l]) {
|
||||||
|
tmp[j] = l;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[0] = (tmp[0] << 2) + ((tmp[1] & 0x30) >> 4);
|
||||||
|
buf[1] = ((tmp[1] & 0xf) << 4) + ((tmp[2] & 0x3c) >> 2);
|
||||||
|
buf[2] = ((tmp[2] & 0x3) << 6) + tmp[3];
|
||||||
|
|
||||||
|
if (resize_b64_buf(&decbuf, size + (i - 1)) != 0) {
|
||||||
|
free(decbuf.ptr);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
for (j = 0; (j < i - 1); ++j) {
|
||||||
|
decbuf.ptr[size++] = buf[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resize_b64_buf(&decbuf, size + 1) != 0) {
|
||||||
|
free(decbuf.ptr);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
decbuf.ptr[size] = '\0';
|
||||||
|
|
||||||
|
if (decode_sz != NULL) {
|
||||||
|
*decode_sz = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (unsigned char*)decbuf.ptr;
|
||||||
|
}
|
@ -10,6 +10,7 @@
|
|||||||
#include "lfvector.h"
|
#include "lfvector.h"
|
||||||
#include "lfmath.h"
|
#include "lfmath.h"
|
||||||
#include "lfstring.h"
|
#include "lfstring.h"
|
||||||
|
#include "lfcrypto.h"
|
||||||
|
|
||||||
#if defined(__APPLE__) || defined(__MACH__)
|
#if defined(__APPLE__) || defined(__MACH__)
|
||||||
#include "lfmacos.h"
|
#include "lfmacos.h"
|
||||||
@ -308,6 +309,25 @@ void test_string() {
|
|||||||
printf("Passes all string tests\n");
|
printf("Passes all string tests\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_crypto() {
|
||||||
|
char *in = "BUTT";
|
||||||
|
char *s = b64_encode(in, strlen(in));
|
||||||
|
assert(strcmp(s, "QlVUVA==") == 0);
|
||||||
|
free(s);
|
||||||
|
|
||||||
|
char *in2 = "a longer base64 test, apparently";
|
||||||
|
s = b64_encode(in2, strlen(in2));
|
||||||
|
assert(strcmp(s, "YSBsb25nZXIgYmFzZTY0IHRlc3QsIGFwcGFyZW50bHk=") == 0);
|
||||||
|
free(s);
|
||||||
|
|
||||||
|
char *out2 = "YSBsb25nZXIgYmFzZTY0IHRlc3QsIGFwcGFyZW50bHk=";
|
||||||
|
size_t s_sz = 0;
|
||||||
|
s = (char *)b64_decode(out2, strlen(out2), &s_sz);
|
||||||
|
assert(strcmp(s, "a longer base64 test, apparently") == 0);
|
||||||
|
assert(strlen(s) == s_sz);
|
||||||
|
free(s);
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(__APPLE__) || defined(__MACH__)
|
#if defined(__APPLE__) || defined(__MACH__)
|
||||||
void test_macos() {
|
void test_macos() {
|
||||||
printf("\n--- macOS TEST ---\n");
|
printf("\n--- macOS TEST ---\n");
|
||||||
@ -331,6 +351,7 @@ int main() {
|
|||||||
test_math();
|
test_math();
|
||||||
test_vector();
|
test_vector();
|
||||||
test_string();
|
test_string();
|
||||||
|
test_crypto();
|
||||||
|
|
||||||
#if defined(__APPLE__) || defined(__MACH__)
|
#if defined(__APPLE__) || defined(__MACH__)
|
||||||
test_macos();
|
test_macos();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user