Commit 69a144b4 authored by Tomáš Stefan's avatar Tomáš Stefan

Compute hash within the range specified

added openssl library
parent 5be1315c
......@@ -4,9 +4,14 @@ project(pdf_sigil)
set(CMAKE_C_STANDARD 11)
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -pedantic")
# add OpenSSL
#set (OPENSSL_USE_STATIC_LIBS TRUE)
#include(FindOpenSSL)
#find_package(OpenSSL REQUIRED)
# header files
include_directories(include)
#include_directories(${OPENSSL_INCLUDE_DIR})
file(GLOB LIB_SRC "lib/*.c")
set (TEST_SRC "test/test.c")
......@@ -15,6 +20,11 @@ set (TEST_SRC "test/test.c")
add_library(pdf-sigil_static STATIC ${LIB_SRC})
add_library(pdf-sigil_shared SHARED ${LIB_SRC})
#target_link_libraries(pdf-sigil_static ${OPENSSL_LIBRARIES} dl pthread)
#target_link_libraries(pdf-sigil_shared ${OPENSSL_LIBRARIES} dl pthread)
target_link_libraries(pdf-sigil_static crypto)
target_link_libraries(pdf-sigil_shared crypto)
# build selftest executable
add_executable(selftest ${TEST_SRC})
target_link_libraries(selftest pdf-sigil_static)
......
......@@ -27,6 +27,9 @@
// previous cross-reference sections (caused by cyclic links)
#define MAX_FILE_UPDATES 1024
// maximum size we give to hash function at once
#define HASH_UPDATE_SIZE 1024
// validate values
int sigil_config_self_test(int verbosity);
......
......@@ -46,5 +46,6 @@
#define ERR_NO_DATA 6
#define ERR_END_OF_DICT 7
#define ERR_NO_SIGNATURE 8
#define ERR_OPENSSL 9
#endif /* PDF_SIGIL_CONSTANTS_H */
#ifndef PDF_SIGIL_CRYPTOGRAPHY_H
#define PDF_SIGIL_CRYPTOGRAPHY_H
#include "types.h"
sigil_err_t compute_sha1_hash_over_range(sigil_t *sgl);
int sigil_sigil_self_test(int verbosity);
#endif /* PDF_SIGIL_CRYPTOGRAPHY_H */
......@@ -14,6 +14,10 @@ sigil_err_t sigil_verify(sigil_t *sgl);
// ... get functions TODO
void cert_free(cert_t *cert);
void contents_free(sigil_t *sgl);
void sigil_free(sigil_t **sgl);
int sigil_sigil_self_test(int verbosity);
......
#ifndef PDF_SIGIL_TYPES_H
#define PDF_SIGIL_TYPES_H
#include <openssl/evp.h> // EVP_MAX_MD_SIZE
#include <stdint.h> // uint32_t
#include <stdio.h>
......@@ -65,25 +66,27 @@ typedef struct {
} pdf_data_t;
typedef struct {
pdf_data_t pdf_data;
short pdf_x, /* numbers from PDF header */
pdf_y; /* %PDF-<pdf_x>.<pdf_y> */
short xref_type;
xref_t *xref;
reference_t ref_catalog_dict;
reference_t ref_acroform;
size_t offset_acroform;
reference_t ref_sig_field;
reference_t ref_sig_dict;
size_t offset_sig_dict;
ref_array_t fields;
size_t pdf_start_offset; /* offset of %PDF-x.y */
size_t startxref;
size_t sig_flags;
subfilter_t subfilter;
range_t *byte_range;
cert_t *certificates;
contents_t *contents;
pdf_data_t pdf_data;
short pdf_x, /* numbers from PDF header */
pdf_y; /* %PDF-<pdf_x>.<pdf_y> */
short xref_type;
xref_t *xref;
reference_t ref_catalog_dict;
reference_t ref_acroform;
size_t offset_acroform;
reference_t ref_sig_field;
reference_t ref_sig_dict;
size_t offset_sig_dict;
ref_array_t fields;
size_t pdf_start_offset; /* offset of %PDF-x.y */
size_t startxref;
size_t sig_flags;
subfilter_t subfilter;
range_t *byte_range;
cert_t *certificates;
contents_t *contents;
unsigned char computed_hash[EVP_MAX_MD_SIZE];
unsigned int computed_hash_len;
} sigil_t;
#endif /* PDF_SIGIL_TYPES_H */
......@@ -172,9 +172,6 @@ sigil_err_t pdf_move_pos_abs(sigil_t *sgl, size_t position)
if (sgl == NULL)
return ERR_PARAMETER;
if (position == 0)
return ERR_NO;
if (sgl->pdf_data.buffer != NULL) {
if (position > sgl->pdf_data.size - 1)
return ERR_IO;
......
......@@ -5,6 +5,7 @@
#include "config.h"
#include "constants.h"
#include "types.h"
#include "sigil.h"
sigil_err_t parse_one_cert(sigil_t *sgl, cert_t **result)
......@@ -17,9 +18,10 @@ sigil_err_t parse_one_cert(sigil_t *sgl, cert_t **result)
if (sgl == NULL || result == NULL)
return ERR_PARAMETER;
if (*result != NULL)
; // TODO free result
*result = NULL;
if (*result != NULL) {
cert_free(*result);
*result = NULL;
}
if ((err = parse_word(sgl, "<")) != ERR_NO)
return err;
......
......@@ -69,6 +69,14 @@ int sigil_config_self_test(int verbosity)
print_test_result(1, verbosity);
// TEST: HASH_UPDATE_SIZE
print_test_item("HASH_UPDATE_SIZE", verbosity);
if (HASH_UPDATE_SIZE < 1)
goto failed;
print_test_result(1, verbosity);
// all tests done
print_module_result(1, verbosity);
return 0;
......
......@@ -5,6 +5,7 @@
#include "constants.h"
#include "contents.h"
#include "types.h"
#include "sigil.h"
sigil_err_t parse_contents(sigil_t *sgl)
......@@ -21,7 +22,7 @@ sigil_err_t parse_contents(sigil_t *sgl)
return err;
if (sgl->contents != NULL)
; // TODO free contents
contents_free(sgl);
if ((err = parse_word(sgl, "<")) != ERR_NO)
return err;
......
#include <openssl/evp.h>
#include <types.h>
#include "auxiliary.h"
#include "config.h"
#include "constants.h"
#include "cryptography.h"
#include "types.h"
sigil_err_t compute_sha1_hash_over_range(sigil_t *sgl)
{
sigil_err_t err;
EVP_MD_CTX *ctx;
range_t *range;
size_t bytes_left;
char *current_data;
size_t current_length;
size_t read_size;
if (sgl == NULL || sgl->byte_range == NULL)
return ERR_PARAMETER;
current_data = malloc(sizeof(*current_data) * (HASH_UPDATE_SIZE + 1));
if (current_data == NULL)
return ERR_ALLOCATION;
sigil_zeroize(current_data, sizeof(*current_data) * (HASH_UPDATE_SIZE + 1));
// initialize context
if ((ctx = EVP_MD_CTX_create()) == NULL)
return ERR_ALLOCATION;
if(EVP_DigestInit_ex(ctx, EVP_sha1(), NULL) != 1) {
err = ERR_OPENSSL;
goto failed;
}
range = sgl->byte_range;
while (range != NULL) {
err = pdf_move_pos_abs(sgl, range->start);
if (err != ERR_NO)
return err;
bytes_left = range->length;
while (bytes_left > 0) {
current_length = MIN(HASH_UPDATE_SIZE, bytes_left);
err = pdf_read(sgl, current_length, current_data, &read_size);
if (err != ERR_NO)
return err;
if (current_length != read_size)
return ERR_IO;
if (EVP_DigestUpdate(ctx, current_data, current_length) != 1) {
err = ERR_OPENSSL;
goto failed;
}
bytes_left -= current_length;
}
range = range->next;
}
// process last pieces of data from context
if (EVP_DigestFinal_ex(ctx, sgl->computed_hash, &(sgl->computed_hash_len)) != 1) {
err = ERR_OPENSSL;
goto failed;
}
EVP_MD_CTX_destroy(ctx);
return ERR_NO;
failed:
if (ctx != NULL)
EVP_MD_CTX_destroy(ctx);
return err;
}
\ No newline at end of file
......@@ -76,7 +76,8 @@ static sigil_err_t parse_byte_range(sigil_t *sgl)
if (err != ERR_NO)
return err;
// TODO add some checks for start and length
if (start + length > sgl->pdf_data.size)
return ERR_PDF_CONTENT;
if (*byte_range == NULL) {
*byte_range = malloc(sizeof(**byte_range));
......
......@@ -7,6 +7,7 @@
#include "catalog_dict.h"
#include "config.h"
#include "constants.h"
#include "cryptography.h"
#include "header.h"
#include "sig_dict.h"
#include "sig_field.h"
......@@ -26,6 +27,8 @@ sigil_err_t sigil_init(sigil_t **sgl)
return ERR_ALLOCATION;
sigil_zeroize(*sgl, sizeof(*sgl));
sigil_zeroize((*sgl)->computed_hash,
sizeof(*(*sgl)->computed_hash) * EVP_MAX_MD_SIZE);
// set default values
(*sgl)->pdf_data.file = NULL;
......@@ -56,6 +59,8 @@ sigil_err_t sigil_init(sigil_t **sgl)
(*sgl)->byte_range = NULL;
(*sgl)->certificates = NULL;
(*sgl)->contents = NULL;
(*sgl)->computed_hash_len = 0;
return ERR_NO;
}
......@@ -80,7 +85,7 @@ sigil_err_t sigil_set_pdf_file(sigil_t *sgl, FILE *pdf_file)
return ERR_IO;
// - 2) read current position
sgl->pdf_data.size = (size_t)(ftell(sgl->pdf_data.file) - 1);
sgl->pdf_data.size = (size_t)ftell(sgl->pdf_data.file);
if (sgl->pdf_data.size < 0)
return ERR_IO;
......@@ -181,6 +186,17 @@ sigil_err_t sigil_set_pdf_buffer(sigil_t *sgl, char *pdf_content, size_t size)
return ERR_NO;
}
static sigil_err_t sigil_verify_adbe_x509_rsa_sha1(sigil_t *sgl)
{
sigil_err_t err;
err = compute_sha1_hash_over_range(sgl);
if (err != ERR_NO)
return err;
}
sigil_err_t sigil_verify(sigil_t *sgl)
{
sigil_err_t err;
......@@ -251,8 +267,11 @@ sigil_err_t sigil_verify(sigil_t *sgl)
switch (sgl->subfilter) {
case SUBFILTER_adbe_x509_rsa_sha1:
err = sigil_verify_adbe_x509_rsa_sha1(sgl);
if (err != ERR_NO)
return err;
break;
return ERR_NO;
default:
return ERR_NOT_IMPLEMENTED;
}
......@@ -270,7 +289,7 @@ static void range_free(range_t *range)
free(range);
}
static void cert_free(cert_t *cert)
void cert_free(cert_t *cert)
{
if (cert == NULL)
return;
......@@ -283,6 +302,18 @@ static void cert_free(cert_t *cert)
free(cert);
}
void contents_free(sigil_t *sgl)
{
if (sgl == NULL || sgl->contents == NULL)
return;
if (sgl->contents->contents_hex != NULL)
free(sgl->contents->contents_hex);
free(sgl->contents);
sgl->contents = NULL;
}
void sigil_free(sigil_t **sgl)
{
if (sgl == NULL || *sgl == NULL)
......@@ -318,12 +349,8 @@ void sigil_free(sigil_t **sgl)
if ((*sgl)->certificates != NULL)
cert_free((*sgl)->certificates);
if ((*sgl)->contents != NULL) {
if ((*sgl)->contents->contents_hex != NULL)
free((*sgl)->contents->contents_hex);
free((*sgl)->contents);
}
if ((*sgl)->contents != NULL)
contents_free(*sgl);
free(*sgl);
*sgl = NULL;
......@@ -350,6 +377,26 @@ int sigil_sigil_self_test(int verbosity)
print_test_result(1, verbosity);
// TEST: correct value of file size
print_test_item("file size", verbosity);
{
sgl = test_prepare_sgl_path("test/EduLib__adbe.x509.rsa_sha1.pdf");
if (sgl == NULL)
goto failed;
if (sgl->pdf_data.size != 60457)
goto failed;
// TODO test verification result
sigil_free(&sgl);
}
print_test_result(1, verbosity);
// TEST: fn sigil_verify with subfilter x509.rsa_sha1
print_test_item("VERIFY x509.rsa_sha1", verbosity);
......
#include <stdlib.h>
#include <string.h>
#include <types.h>
#include "auxiliary.h"
#include "config.h"
#include "constants.h"
......@@ -113,7 +114,6 @@ void xref_free(xref_t *xref)
sigil_err_t read_startxref(sigil_t *sgl)
{
sigil_err_t err;
size_t file_size;
size_t offset;
size_t read_size;
char tmp[10];
......@@ -121,10 +121,8 @@ sigil_err_t read_startxref(sigil_t *sgl)
if (sgl == NULL)
return ERR_PARAMETER;
file_size = sgl->pdf_data.size - 1;
for (offset = 9; offset < XREF_SEARCH_OFFSET; offset++) {
if ((err = pdf_move_pos_abs(sgl, file_size - offset)) != ERR_NO)
if ((err = pdf_move_pos_abs(sgl, sgl->pdf_data.size - offset)) != ERR_NO)
return err;
err = pdf_read(sgl, 9, tmp, &read_size);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment