Implement working Digest headers included in HTTP Signature for all outgoing posts

master
teknomunk 1 year ago
parent 7f764b082c
commit 0ecd13752f

@ -73,7 +73,7 @@ static bool process_envelope( struct outbox_envelope* env )
}
struct http_signature hs;
if( !http_signature_make( inbox, keys, &hs/*, postdata */ ) ) {
if( !http_signature_make( inbox, keys, &hs, postdata ) ) {
printf( "! Failed to make HTTP signature\n" );
goto failed;
}
@ -82,7 +82,7 @@ static bool process_envelope( struct outbox_envelope* env )
snprintf( date_header, sizeof(date_header), "Date: %s", hs.date );
char sign_header[512];
snprintf( sign_header, sizeof(sign_header), "Signature: keyId=\"https://%s/owner/actor#mainKey\",headers=\"(request-target) host date\",signature=\"%s\"",
snprintf( sign_header, sizeof(sign_header), "Signature: keyId=\"https://%s/owner/actor#mainKey\",headers=\"(request-target) host date content-length digest\",signature=\"%s\"",
g_server_name,
hs.signature
);
@ -90,6 +90,12 @@ static bool process_envelope( struct outbox_envelope* env )
char user_agent[512];
snprintf( user_agent, sizeof(user_agent), "User-Agent: curl (Apogee/0.1; +https://%s/)", g_server_name );
char digest_header[512];
snprintf( digest_header, sizeof(digest_header), "Digest: %s", hs.digest );
char content_length_header[512];
snprintf( content_length_header, sizeof(content_length_header), "Content-Length: %d", hs.content_length );
printf( "Performing post to %s\n", inbox );
long status_code = -1;
const void* request[] = {
@ -97,6 +103,8 @@ static bool process_envelope( struct outbox_envelope* env )
HTTP_REQ_HEADER, user_agent,
HTTP_REQ_HEADER, date_header,
HTTP_REQ_HEADER, sign_header,
HTTP_REQ_HEADER, content_length_header,
HTTP_REQ_HEADER, digest_header,
HTTP_REQ_HEADER, "Content-Type: application/activity+json",
HTTP_REQ_POSTDATA, postdata,
HTTP_REQ_RESULT_STATUS, &status_code,
@ -105,8 +113,10 @@ static bool process_envelope( struct outbox_envelope* env )
// POST to inbox
printf( "\n\nRequest result:\n" );
fflush(stdout);
http_client_do(request);
printf( "\n\n" );
fflush(stdout);
http_signature_free( &hs );

@ -4,6 +4,7 @@
#include "model/ap/inbox_envelope.h"
#include "model/crypto/keys.h"
#include "model/crypto/http_sign.h"
#include "format.h"
#include <stdio.h>
#include <stdlib.h>
@ -78,19 +79,19 @@ static bool test_http_signature_2()
keys = crypto_keys_new();
crypto_keys_load_private( keys, "assets/test.private.pem" );
if( !http_signature_make( "https://example.com/inbox", keys, &hs ) ) { goto failed; }
if( !http_signature_make( "https://example.com/inbox", keys, &hs, "{\"hello\": \"world\"}" ) ) { goto failed; }
char signature_header[512];
snprintf( signature_header, sizeof(signature_header), "keyId=\"Test\",headers=\"(request-target) host date\",signature=\"%s\"", hs.signature );
snprintf( signature_header, sizeof(signature_header), "keyId=\"Test\",headers=\"(request-target) host date content-length digest\",signature=\"%s\"", hs.signature );
//printf( "Signature: %s\n", signature_header );
printf( "Signature: %s\n", signature_header );
struct http_header headers[] = {
{ .key = "Host", .value = "example.com" },
{ .key = "Date", .value = hs.date },
{ .key = "Content-Type", .value = "application/json" },
{ .key = "Digest", .value = "SHA-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=" },
{ .key = "Content-Length", .value = "18" },
{ .key = "Digest", .value = hs.digest } , //"SHA-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=" },
{ .key = "Content-Length", .value = aformat( "%d", hs.content_length ) }, // "18" },
{ .key = "Signature", .value = signature_header },
};

@ -1 +1 @@
Subproject commit 71006190b8e05366e355455174bcf2308805686c
Subproject commit da305b421b082bdfdbbb7d68287a84e5eeb7ec46

@ -111,6 +111,16 @@ int main( int argc, char* argv[] )
const char* arg = argv[i];
if( sscanf(arg,"--section=%d",&section) ) {
} else if( 0 == strcmp(argv[i],"--test") ) {
section = 3;
} else if( 0 == strcmp(argv[i],"--webserver") ) {
section = 0;
} else if( 0 == strcmp(argv[i],"--inbox") ) {
section = 1;
} else if( 0 == strcmp(argv[i],"--outbox") ) {
section = 2;
} else if( 0 == strcmp(argv[i],"--reindex") ) {
section = 3;
} else if( 0 == strcmp(argv[i],"--devel") ) {
section = 100;
} else {

@ -2,6 +2,7 @@
#include "sha256/sha256.h"
#include "http/server/header.h"
#include "format.h"
#include "model/account.h"
#include "model/crypto/keys.h"
@ -14,7 +15,7 @@
#include <string.h>
#include <time.h>
bool http_signature_make( const char* inbox, struct crypto_keys* keys, struct http_signature* sign )
bool http_signature_make( const char* inbox, struct crypto_keys* keys, struct http_signature* sign, const char* postdata )
{
memset(sign,0,sizeof(*sign));
@ -46,14 +47,25 @@ bool http_signature_make( const char* inbox, struct crypto_keys* keys, struct ht
);
sign->date = strdup(date);
// Calculate Digest
char raw_hash[32];
sign->content_length = strlen(postdata);
sha256_easy_hash( postdata, sign->content_length, raw_hash );
char* base64_hash = base64_strict_encode(raw_hash,32);
sign->digest = aformat( "SHA-256=%s", base64_hash );
free(base64_hash);
// Build hash line
char hash_line[512];
int size = snprintf( hash_line, 512, "(request-target): post %s\nhost: %s\ndate: %s", path, host, date );
//printf( "\nbuilding hash_line = %s|\n\n", hash_line );
int size = snprintf( hash_line, 512,
"(request-target): post %s\nhost: %s\ndate: %s\ncontent-length: %d\ndigest: %s",
path, host, date, sign->content_length, sign->digest
);
printf( "\nbuilding hash_line = %s|\n\n", hash_line );
// sign
sign->signature = crypto_keys_sign( keys, hash_line, strlen(hash_line) );
//printf( "Signature: %s\n", sign->signature );
printf( "Signature: %s\n", sign->signature );
return true;
}

@ -10,9 +10,11 @@ struct http_signature
char* host;
char* date;
char* signature;
char* digest;
int content_length;
};
bool http_signature_make( const char* inbox, struct crypto_keys* keys, struct http_signature* sign );
bool http_signature_make( const char* inbox, struct crypto_keys* keys, struct http_signature* sign, const char* postdata );
void http_signature_free( struct http_signature* sign );
bool http_signature_validate( struct ap_envelope* env, const char* request_target, const char* expected_actor );

Loading…
Cancel
Save