Start crypto implementation, remove debug printfs, partial application of s/reverse_index/uri_index/, fix memory leak in rie_reader, start writing outbox processing
parent
ec7147dfff
commit
b7bef499e6
@ -1,2 +1,2 @@
|
||||
FLAGS="-g -MP -MD -Os"
|
||||
LDFLAGS = "-lcurl"
|
||||
LDFLAGS = "-lcurl -lssl -lcrypto"
|
||||
|
@ -0,0 +1,35 @@
|
||||
#include "outbox.h"
|
||||
|
||||
#include "fs_list.h"
|
||||
|
||||
#include "model/crypto/keys.h"
|
||||
#include "sha256/sha256.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static void process_one()
|
||||
{
|
||||
int tail = fs_list_get("data/outbox/TAIL");
|
||||
printf( "To handle: %d\n", tail );
|
||||
}
|
||||
|
||||
void process_outbox()
|
||||
{
|
||||
struct crypto_keys* keys = crypto_keys_new();
|
||||
|
||||
if( !crypto_keys_load_private( keys, "data/owner/private.pem" ) ) {
|
||||
printf( "Failed to load private key\n" );
|
||||
}
|
||||
|
||||
char hash[32];
|
||||
sha256_easy_hash( "Hello, World!", 13, hash );
|
||||
|
||||
char* signature = crypto_keys_sign( keys, hash, 32 );
|
||||
printf( "signature = %s\n", signature );
|
||||
free(signature);
|
||||
|
||||
crypto_keys_free(keys);
|
||||
|
||||
exit(0);
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
void process_outbox();
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 0c8f1e1d52b6dd89876c3f3c05a28c468bf68d43
|
||||
Subproject commit 0f07cd429652690aba5a6dc8908072f75b1df03a
|
@ -0,0 +1,131 @@
|
||||
#include "keys.h"
|
||||
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/evp.h>
|
||||
|
||||
struct crypto_keys
|
||||
{
|
||||
EVP_PKEY* pubkey;
|
||||
EVP_PKEY* privkey;
|
||||
};
|
||||
|
||||
struct crypto_keys* crypto_keys_new()
|
||||
{
|
||||
struct crypto_keys* k;
|
||||
|
||||
k = malloc(sizeof(*k));
|
||||
memset(k,0,sizeof(*k));
|
||||
|
||||
return k;
|
||||
}
|
||||
|
||||
void crypto_keys_free( struct crypto_keys* keys )
|
||||
{
|
||||
if( !keys ) { return; }
|
||||
|
||||
if( keys->pubkey ) {
|
||||
EVP_PKEY_free(keys->pubkey);
|
||||
}
|
||||
if( keys->privkey ) {
|
||||
EVP_PKEY_free(keys->privkey);
|
||||
}
|
||||
|
||||
free(keys);
|
||||
}
|
||||
|
||||
bool crypto_keys_load_private( struct crypto_keys* keys, const char* filename )
|
||||
{
|
||||
if( keys->privkey ) {
|
||||
EVP_PKEY_free( keys->privkey );
|
||||
keys->privkey = NULL;
|
||||
}
|
||||
|
||||
FILE* f = fopen(filename,"r");
|
||||
|
||||
keys->privkey = PEM_read_PrivateKey( f, NULL, NULL, NULL );
|
||||
fclose(f);
|
||||
|
||||
return !!keys->privkey;
|
||||
}
|
||||
|
||||
char* base64_strict_encode( void* v_binary, size_t len )
|
||||
{
|
||||
// RFC 4648 - https://www.rfc-editor.org/rfc/rfc4648.html
|
||||
static const char* alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
enum { pad = '=' };
|
||||
|
||||
uint8_t* binary = v_binary;
|
||||
const int groups = ( len + 2 ) / 3;
|
||||
const int padding = len % 3;
|
||||
|
||||
char* result = malloc( groups * 4 + 1 );
|
||||
result[groups*4] = '\0';
|
||||
|
||||
uint32_t word;
|
||||
char* out = result;
|
||||
for( int remain = len; remain > 0; remain -= 3, binary += 3, out += 4 ) {
|
||||
word = 0;
|
||||
switch( remain ) {
|
||||
default:
|
||||
word |= binary[2] << (8*0);
|
||||
case 2:
|
||||
word |= binary[1] << (8*1);
|
||||
case 1:
|
||||
word |= binary[0] << (8*2);
|
||||
}
|
||||
switch( remain ) {
|
||||
default:
|
||||
out[3] = alphabet[ ( word >> (6*0) ) % 64 ];
|
||||
case 2:
|
||||
out[2] = alphabet[ ( word >> (6*1) ) % 64 ];
|
||||
case 1:
|
||||
out[1] = alphabet[ ( word >> (6*2) ) % 64 ];
|
||||
out[0] = alphabet[ ( word >> (6*3) ) % 64 ];
|
||||
}
|
||||
switch( remain ) {
|
||||
case 1:
|
||||
out[3] = '=';
|
||||
out[2] = '=';
|
||||
break;
|
||||
case 2:
|
||||
out[3] = '=';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
char* crypto_keys_sign( struct crypto_keys* keys, void* data, unsigned int size )
|
||||
{
|
||||
char* result = NULL;
|
||||
char* sign_binary = NULL;
|
||||
EVP_PKEY_CTX* ctx = NULL;
|
||||
|
||||
if( !keys->privkey ) { return NULL; }
|
||||
|
||||
// Setup for signature
|
||||
// Code based on https://www.openssl.org/docs/man3.1/man3/EVP_PKEY_sign.html
|
||||
ctx = EVP_PKEY_CTX_new(keys->privkey, NULL /* no engine */);
|
||||
if( !ctx ) { goto failed; }
|
||||
|
||||
if( EVP_PKEY_sign_init(ctx) <= 0 ) { goto failed; }
|
||||
if( EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0 ) { goto failed; }
|
||||
if( EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha256()) <= 0 ) { goto failed; }
|
||||
|
||||
size_t siglen;
|
||||
if( EVP_PKEY_sign(ctx, NULL, &siglen, data, size ) <= 0 ) { goto failed; }
|
||||
|
||||
sign_binary = malloc(siglen);
|
||||
|
||||
if( EVP_PKEY_sign(ctx, sign_binary, &siglen, data, size) <= 0 ) { goto failed; }
|
||||
|
||||
result = base64_strict_encode( sign_binary, siglen );
|
||||
cleanup:
|
||||
free(sign_binary);
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
return result;
|
||||
failed:
|
||||
free(result); result = NULL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
struct crypto_keys;
|
||||
|
||||
struct crypto_keys* crypto_keys_new();
|
||||
void crypto_keys_free( struct crypto_keys* keys );
|
||||
|
||||
bool crypto_keys_load_public ( struct crypto_keys* keys, const char* filename );
|
||||
bool crypto_keys_load_private( struct crypto_keys* keys, const char* filename );
|
||||
|
||||
char* crypto_keys_sign( struct crypto_keys* keys, void* data, unsigned int size );
|
||||
bool crypto_keys_verify( struct crypto_keys* keys, void* data, unsigned int size );
|
||||
|
||||
char* base64_strict_encode( void* v_binary, size_t len );
|
||||
|
Loading…
Reference in new issue