# 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 ;
}