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.

131 lines
3.7 KiB
C

#include "crypto.h"
// Submodules
#include "http/server/header.h"
#include "util/format.h"
// Model
#include "model/inbox_envelope.h"
#include "model/crypto/keys.h"
#include "model/crypto/http_sign.h"
// Standard Library
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static bool test_signatures()
{
struct crypto_keys* keys = crypto_keys_new();
if( !crypto_keys_load_public( keys, "assets/test.public.pem" ) ) {
printf( "[FAIL] unable to load assets/test.public.pem\n" );
return false;
}
if( !crypto_keys_load_private( keys, "assets/test.private.pem" ) ) {
printf( "[FAIL] unable to load assets/test.private.pem\n" );
return false;
}
char* data = "This is a test of the emergency broadcast system.";
char* sign = crypto_keys_sign( keys, data, strlen(data) );
if( !sign ) {
printf( "[FAIL] unable to sign data\n" );
return false;
}
free(sign);
crypto_keys_free(keys);
return true;
}
static bool test_http_signature()
{
// https://datatracker.ietf.org/doc/html/draft-cavage-http-signatures-08#C.3 All Headers Test
struct http_header headers[] = {
{ .key = "Host", .value = "example.com" },
{ .key = "Date", .value = "Thu, 05 Jan 2014 21:31:40 GMT" },
{ .key = "Content-Type", .value = "application/json" },
{ .key = "Digest", .value = "SHA-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=" },
{ .key = "Content-Length", .value = "18" },
{ .key = "Signature", .value =
"keyId=\"Test\",algorithm=\"rsa-sha256\","
"headers=\"(request-target) host date content-type digest content-length\","
"signature=\"Ef7MlxLXoBovhil3AlyjtBwAL9g4TN3tibLj7uuNB3CROat/9Kae"
"Q4hW2NiJ+pZ6HQEOx9vYZAyi+7cmIkmJszJCut5kQLAwuX+Ms/mUFvpKlSo9StS"
"2bMXDBNjOh4Auj774GFj4gwjS+3NhFeoqyr/MuN6HsEnkvn6zdgfE2i0=\""
},
};
struct ap_envelope env = {
.when = "1388957500000000000",
.headers = {
.items = headers,
.count = sizeof(headers) / sizeof(headers[0]),
},
.validated = false,
.body = "{\"hello\": \"world\"}",
};
return http_signature_validate( &env, "post /foo?param=value&pet=dog", "Test" );
}
static bool test_http_signature_2()
{
struct crypto_keys* keys = NULL;
struct http_signature hs;
bool result = false;
memset(&hs,0,sizeof(hs));
keys = crypto_keys_new();
crypto_keys_load_private( keys, "assets/test.private.pem" );
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 content-length digest\",signature=\"%s\"", hs.signature );
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 = hs.digest } , //"SHA-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=" },
{ .key = "Content-Length", .value = aformat( "%d", hs.content_length ) }, // "18" },
{ .key = "Signature", .value = signature_header },
};
struct ap_envelope env = {
.when = "1388957500000000000",
.headers = {
.items = headers,
.count = sizeof(headers) / sizeof(headers[0]),
},
.validated = false,
.body = "{\"hello\": \"world\"}",
};
result = http_signature_validate( &env, "post /inbox", "Test" );
cleanup:
http_signature_free(&hs);
crypto_keys_free(keys);
return result;
failed:
result = false;
goto cleanup;
}
bool test_crypto()
{
if( !test_signatures() ) { printf( "[FAIL] test_signatures()\n" ); return false; }
if( !test_http_signature() ) { printf( "[FAIL] test_http_signature()\n" ); return false; }
if( !test_http_signature_2() ) { printf( "[FAIL] test_http_signature_2()\n" ); return false; }
return true;
}