You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
154 lines
4.7 KiB
C
154 lines
4.7 KiB
C
1 year ago
|
#define _GNU_SOURCE
|
||
1 year ago
|
#include "rsa_signature_2017.h"
|
||
1 year ago
|
|
||
1 year ago
|
#include "../object.h"
|
||
1 year ago
|
|
||
|
// TODO: figure out how to remove this dependency
|
||
1 year ago
|
#include "model/crypto/keys.h"
|
||
1 year ago
|
|
||
|
#include "rdf/serial.h"
|
||
1 year ago
|
#include "rdf/memory_store.h"
|
||
|
#include "rdf/normalize.h"
|
||
|
|
||
1 year ago
|
#include "sha256/sha256.h"
|
||
|
|
||
|
#include "collections/collection.h"
|
||
1 year ago
|
|
||
|
#include <string.h>
|
||
1 year ago
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <stddef.h>
|
||
|
|
||
|
static char* type_filter( const char* name )
|
||
|
{
|
||
|
char* res;
|
||
|
asprintf( &res, "<https://www.w3.org/ns/activitystreams#%s>", name );
|
||
|
return res;
|
||
|
}
|
||
|
struct rdf_enum types = {
|
||
1 year ago
|
.items = (struct rdf_enum_item*)ap_object_type_enum,
|
||
1 year ago
|
.filter = type_filter,
|
||
|
};
|
||
|
|
||
1 year ago
|
struct rdf_serialize_field ap_activity_rdf[];
|
||
1 year ago
|
|
||
|
static struct rdf_serialize_field activity_ref_types[] = {
|
||
|
{ (char*)apaot_ref, offsetof( struct ap_activity, object.ref ), &rdf_string_field },
|
||
1 year ago
|
{ (char*)apaot_activity, offsetof( struct ap_activity, object.ptr ), &rdf_object_field, &ap_activity_rdf },
|
||
1 year ago
|
{ NULL },
|
||
|
};
|
||
|
|
||
1 year ago
|
struct rdf_serialize_field ap_activity_rdf[] = {
|
||
1 year ago
|
{ "", offsetof( struct ap_activity, id ), &rdf_id_field },
|
||
|
{ "<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>", offsetof( struct ap_activity, type ), &rdf_enum_field, &types },
|
||
1 year ago
|
{ "<https://www.w3.org/ns/activitystreams#actor>", offsetof( struct ap_activity, actor ), &rdf_string_ref_field },
|
||
1 year ago
|
{ "<https://www.w3.org/ns/activitystreams#content>", offsetof( struct ap_activity, content ), &rdf_string_field },
|
||
|
{ "<https://www.w3.org/ns/activitystreams#published>", offsetof( struct ap_activity, published ), &rdf_date_field },
|
||
1 year ago
|
{ "<https://www.w3.org/ns/activitystreams#to>", offsetof( struct ap_activity, to ), &rdf_array_of_field, &rdf_string_ref_field },
|
||
|
{ "<https://www.w3.org/ns/activitystreams#cc>", offsetof( struct ap_activity, cc ), &rdf_array_of_field, &rdf_string_ref_field },
|
||
|
{ "<https://www.w3.org/ns/activitystreams#bcc>", offsetof( struct ap_activity, bcc ), &rdf_array_of_field, &rdf_string_ref_field },
|
||
1 year ago
|
{ "<https://www.w3.org/ns/activitystreams#object>", offsetof( struct ap_activity, object.tag ), &rdf_tagged_union_field, activity_ref_types },
|
||
|
{ NULL, sizeof(struct ap_activity) },
|
||
|
};
|
||
|
|
||
1 year ago
|
struct rdf_serialize_field ap_activity_signature_rdf[] = {
|
||
1 year ago
|
{ "", 0, &rdf_id_blank },
|
||
|
{ "<http://purl.org/dc/terms/creator>", offsetof( struct ap_signature, creator ), &rdf_string_ref_field },
|
||
|
{ "<http://purl.org/dc/terms/created>", offsetof( struct ap_signature, created ), &rdf_date_field },
|
||
1 year ago
|
{ NULL },
|
||
1 year ago
|
};
|
||
1 year ago
|
|
||
1 year ago
|
|
||
|
static void write_normalized_rdf( struct rdf_serialize_field* layout, void* object, FILE* f )
|
||
1 year ago
|
{
|
||
1 year ago
|
// Serialize activity to RDF
|
||
1 year ago
|
struct rdf_serializer rs;
|
||
|
memset(&rs,0,sizeof(rs));
|
||
1 year ago
|
rs.subject = strdup("");
|
||
1 year ago
|
rs.graph = strdup(".");
|
||
|
|
||
1 year ago
|
struct rdf_memory_store* ms = rdf_memory_store_new();
|
||
|
rdf_memory_store_init_serializer( ms, &rs );
|
||
1 year ago
|
rdf_serialize_object( &rs, layout, object );
|
||
1 year ago
|
|
||
|
// Normalize
|
||
1 year ago
|
struct collection i;
|
||
1 year ago
|
rdf_memory_store_as_collection( ms, &i );
|
||
|
rdf_normalize(i);
|
||
|
|
||
1 year ago
|
rdf_memory_store_dump( ms, f );
|
||
|
|
||
|
rdf_memory_store_free(ms);
|
||
|
|
||
|
free((char*)rs.subject);
|
||
|
free((char*)rs.graph);
|
||
|
}
|
||
|
|
||
|
void ap_activity_write_normalized_rdf( struct ap_activity* act, FILE* out )
|
||
|
{
|
||
|
write_normalized_rdf( ap_activity_rdf, act, out );
|
||
|
}
|
||
|
|
||
|
static char* serialize_normalized_object( struct rdf_serialize_field* layout, void* object, size_t* result_size )
|
||
|
{
|
||
1 year ago
|
char* outbuf = NULL;
|
||
1 year ago
|
|
||
1 year ago
|
FILE* f = open_memstream( &outbuf, result_size );
|
||
|
if( !f ) {
|
||
|
printf( "Error opening memstream\n" );
|
||
1 year ago
|
return NULL;
|
||
1 year ago
|
}
|
||
1 year ago
|
write_normalized_rdf( layout, object, f );
|
||
1 year ago
|
fclose(f);
|
||
1 year ago
|
|
||
1 year ago
|
return outbuf;
|
||
|
}
|
||
|
|
||
1 year ago
|
static bool calculate_hash_for_object( struct rdf_serialize_field* layout, void* object, char* hash )
|
||
|
{
|
||
|
size_t size = 0;
|
||
|
|
||
|
// Serialize to normalized RDF
|
||
|
char* buffer = serialize_normalized_object( layout, object, &size );
|
||
|
if( !buffer ) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// Hash with SHA-256
|
||
|
sha256_easy_hash( buffer, size, &hash[0] );
|
||
|
|
||
|
// Debug
|
||
|
printf( "RDF: \n" );
|
||
|
fwrite( buffer, size, 1, stdout );
|
||
|
printf( "\nHash: " );
|
||
|
for( int i = 0; i < 32; ++i ) {
|
||
|
printf( "%02X", (int)((unsigned char*)hash)[i] );
|
||
|
}
|
||
|
printf( "\n" );
|
||
|
|
||
|
free(buffer);
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool ap_activity_create_rsa_signature_2017( struct ap_activity* act, struct crypto_keys* keys )
|
||
1 year ago
|
{
|
||
1 year ago
|
char* signature_buf = NULL;
|
||
1 year ago
|
printf( "ap_activity_create_rsa_signature_2017\n" );
|
||
|
|
||
1 year ago
|
// Setup signature
|
||
|
asprintf( &act->signature.creator, "%s#main-key", act->actor );
|
||
|
act->signature.created = time(NULL);
|
||
1 year ago
|
|
||
1 year ago
|
char raw_hash[64];
|
||
|
if( !calculate_hash_for_object( ap_activity_rdf, act, &raw_hash[0] ) ) { return NULL; }
|
||
|
if( !calculate_hash_for_object( ap_activity_signature_rdf, &act->signature, &raw_hash[32] ) ) { return NULL; }
|
||
1 year ago
|
|
||
1 year ago
|
char* sign = crypto_keys_sign( keys, raw_hash, 64 );
|
||
1 year ago
|
act->signature.value = sign;
|
||
|
act->signature.type = apst_rsa_signature_2017;
|
||
|
printf( "act->signature = %s\n", sign );
|
||
|
return (act->has_signature = !!act->signature.value);
|
||
1 year ago
|
}
|
||
|
|