Verified Commit 6d65ff50 authored by Tomáš Stefan's avatar Tomáš Stefan
Browse files

command-line tool

parent f3c15bda
Loading
Loading
Loading
Loading
+15 −11
Original line number Diff line number Diff line
@@ -21,16 +21,9 @@ target_link_libraries(pdfsigil crypto)
add_executable(selftest ${TEST_SRC})
target_link_libraries(selftest pdfsigil)

# find Doxygen package for generating the documentation
find_package(Doxygen)
if (DOXYGEN_FOUND)
    add_custom_target(doc ALL
        COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile
        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
        COMMENT "Generating Doxygen documentation")
else (DOXYGEN_FOUND)
    message("Install Doxygen for generation of the documentation")
endif (DOXYGEN_FOUND)
#build pdf-sigil - PoC command-line application
add_executable(pdf-sigil src/pdf-sigil.c)
target_link_libraries(pdf-sigil pdfsigil)

# running selftest
add_custom_target(run_tests ALL
@@ -46,3 +39,14 @@ add_custom_target(run_tests_quiet
    COMMAND selftest --quiet
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)

# generating the documentation with a Doxygen
find_package(Doxygen)
if (DOXYGEN_FOUND)
    add_custom_target(doc ALL
            COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile
            WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
            COMMENT "Generating Doxygen documentation")
else (DOXYGEN_FOUND)
    message("Install Doxygen for generation of the documentation")
endif (DOXYGEN_FOUND)
+3 −0
Original line number Diff line number Diff line
@@ -46,6 +46,9 @@
#define HASH_CMP_RESULT_MATCH           1
#define HASH_CMP_RESULT_DIFFER          2

#define VERIFY_SUCCESS                  0
#define VERIFY_FAILED                   1

#define DEALLOCATE_FILE                 0x01
#define DEALLOCATE_BUFFER               0x02

+11 −9
Original line number Diff line number Diff line
@@ -78,16 +78,17 @@ sigil_err_t sigil_set_trusted_dir(sigil_t *sgl, const char *path_to_dir);
 */
sigil_err_t sigil_verify(sigil_t *sgl);

/** @brief Gets the result from the provided context
/** @brief Get the result from the provided context
 *
 * @param sgl context
 * @param result output - the result of digital signature verification
 * @param result output - the result of digital signature verification,
 *               VERIFY_SUCCESS or VERIFY_FAILED (constants.h)
 * @return ERR_NONE if success
 */
sigil_err_t sigil_get_result(sigil_t *sgl, int *result);

/** @brief Gets the result of a certificate validation phase from the provided
 *         context
/** @brief Get the result of a certificate validation phase from the provided
 *         context, CERT_STATUS_VERIFIED or CERT_STATUS_FAILED (constants.h)
 *
 * @param sgl context
 * @param result output - result of the certificate validation
@@ -95,8 +96,9 @@ sigil_err_t sigil_get_result(sigil_t *sgl, int *result);
 */
sigil_err_t sigil_get_cert_validation_result(sigil_t *sgl, int *result);

/** @brief Gets the result of a data integrity (message digest comparison) phase
 *         from the provided context
/** @brief Get the result of a data integrity (message digest comparison) phase
 *         from the provided context, HASH_CMP_RESULT_MATCH or
 *         HASH_CMP_RESULT_DIFFER (constants.h)
 *
 * @param sgl context
 * @param result output - result of the message digest comparison
@@ -104,7 +106,7 @@ sigil_err_t sigil_get_cert_validation_result(sigil_t *sgl, int *result);
 */
sigil_err_t sigil_get_data_integrity_result(sigil_t *sgl, int *result);

/** @brief Gets the original message digest (from the signature) from the
/** @brief Get the original message digest (from the signature) from the
 *         provided context
 *
 * @param sgl context
@@ -113,7 +115,7 @@ sigil_err_t sigil_get_data_integrity_result(sigil_t *sgl, int *result);
 */
sigil_err_t sigil_get_original_digest(sigil_t *sgl, ASN1_OCTET_STRING **digest);

/** @brief Gets the computed message digest from the provided context
/** @brief Get the computed message digest from the provided context
 *
 * @param sgl context
 * @param digest output - the computed message digest
@@ -127,7 +129,7 @@ sigil_err_t sigil_get_computed_digest(sigil_t *sgl, ASN1_OCTET_STRING **digest);
 */
void sigil_print_digest(const ASN1_OCTET_STRING *digest);

/** @brief Gets the subfilter value from the provided context
/** @brief Get the subfilter value from the provided context
 *
 * @param sgl context
 * @param subfilter output - the subfiter value
+7 −2
Original line number Diff line number Diff line
@@ -358,8 +358,13 @@ sigil_err_t sigil_get_result(sigil_t *sgl, int *result)
            if (err != ERR_NONE)
                return err;

            *result = (cert_res == CERT_STATUS_VERIFIED) &&
                      (digest_res == HASH_CMP_RESULT_MATCH);
            if (cert_res == CERT_STATUS_VERIFIED &&
                digest_res == HASH_CMP_RESULT_MATCH)
            {
                *result = VERIFY_SUCCESS;
            } else {
                *result = VERIFY_FAILED;
            }

            return ERR_NONE;
        default:

src/pdf-sigil.c

0 → 100644
+171 −0
Original line number Diff line number Diff line
#include <stdio.h>
#include <string.h>
#include <sigil.h>
#include <constants.h>

void print_banner(void)
{
    fprintf(stderr,
        "                                            \n"
        "  ____  ____  _____    ____  _       _ _    \n"
        " |  _ \\|  _ \\|  ___|  / ___|(_) __ _(_) | \n"
        " | |_) | | | | |_ ____\\___ \\| |/ _` | | | \n"
        " |  __/| |_| |  _|_____|__) | | (_| | | |   \n"
        " |_|   |____/|_|      |____/|_|\\__, |_|_|  \n"
        "                               |___/        \n"
        "                                            \n"
        " ========================================== \n"
        "                                            \n");
}

void print_help(void)
{
    fprintf(stderr,
            " OPTIONS                                                         \n"
            "     -f, --file                                                  \n"
            "         PDF file with a digital signature for the verification. \n"
            "     -h, --help                                                  \n"
            "         Output a program usage message and exit.                \n"
            "     -q, --quiet                                                 \n"
            "         Do not print anything to standard/error output.         \n"
            "     -td, --trusted-dir                                          \n"
            "         Load all the certificates from a specified folder to a  \n"
            "         storage of the trusted certificates. The certificates   \n"
            "         inside of the folder must be in a hashed form as        \n"
            "         documented in OpenSSL function X509_LOOKUP_hash_dir.    \n"
            "     -tf, --trusted-file                                         \n"
            "         Load the certificate from provided file to a storage of \n"
            "         the trusted certificates.                               \n"
            "     -ts, --trusted-system                                       \n"
            "         Use the system storage of the trusted certificates for  \n"
            "         the verification.                                       \n"
            "                                                                 \n"
            " EXIT STATUS                                                     \n"
            "     0 ... the provided file was successfuly verified            \n"
            "     1 ... the signature is invalid/could not be verified/other  \n"
            "           error occured                                         \n"
    );
}

int main(int argc, char *argv[])
{
    sigil_t *sgl = NULL;
    sigil_err_t err;
    int result = VERIFY_FAILED;
    int ret_code = 1;
    int help = 0;
    int quiet = 0;
    int trusted_system = 0;
    const char *trusted_file = NULL;
    const char *trusted_dir = NULL;
    const char *file = NULL;

    // process parameters from the command line
    for (int pos = 1; pos < argc; pos++) {
        if (strcmp(argv[pos], "-h") == 0 || strcmp(argv[pos], "--help") == 0) {
            help = 1;
            break;
        } else if (strcmp(argv[pos], "-q") == 0 || strcmp(argv[pos], "--quiet") == 0) {
            quiet = 1;
        } else if (strcmp(argv[pos], "-ts") == 0 || strcmp(argv[pos], "--trusted-system") == 0) {
            trusted_system = 1;
        } else if (strcmp(argv[pos], "-tf") == 0 || strcmp(argv[pos], "--trusted-file") == 0) {
            if (++pos >= argc) {
                break;
            }
            trusted_file = argv[pos];
        } else if (strcmp(argv[pos], "-td") == 0 || strcmp(argv[pos], "--trusted-dir") == 0) {
            if (++pos >= argc) {
                break;
            }
            trusted_dir = argv[pos];
        } else if (strcmp(argv[pos], "-f") == 0 || strcmp(argv[pos], "--file") == 0) {
            if (++pos >= argc) {
                break;
            }
            file = argv[pos];
        }
    }

    if (!quiet)
        print_banner();

    if (help) {
        if (!quiet)
            print_help();
        goto end;
    }

    if (file == NULL) {
        if (!quiet)
            print_help();
        goto end;
    }

    // initialize sigil context
    if (sigil_init(&sgl) != ERR_NONE) {
        fprintf(stderr, " ERROR initialize sigil context\n");
        goto end;
    }

    // set PDF file for the verification
    if (sigil_set_pdf_path(sgl, file) != ERR_NONE) {
        fprintf(stderr, " ERROR with provided file\n");
        goto end;
    }

    // set trusted CA certificates
    if (trusted_system) {
        if (sigil_set_trusted_system(sgl) != ERR_NONE) {
            fprintf(stderr, " ERROR setting trusted certificates\n");
            goto end;
        }
    } else if (trusted_file != NULL) {
        if (sigil_set_trusted_file(sgl, trusted_file) != ERR_NONE) {
            fprintf(stderr, " ERROR setting trusted certificates\n");
            goto end;
        }
    } else if (trusted_dir != NULL) {
        if (sigil_set_trusted_dir(sgl, trusted_dir) != ERR_NONE) {
            fprintf(stderr, " ERROR setting trusted certificates\n");
            goto end;
        }
    }

    // verify and save the result to the context
    err = sigil_verify(sgl);
    if (err != ERR_NONE) {
        if (err == ERR_NOT_IMPLEMENTED) {
            fprintf(stderr, " ERROR file uses feature that is not implemented\n");
        } else {
            fprintf(stderr, " ERROR obtaining verification result from the context\n");
        }
        goto end;
    }

    err = sigil_get_result(sgl, &result);
    if (err != ERR_NONE) {
        if (err == ERR_NOT_IMPLEMENTED) {
            fprintf(stderr, " ERROR file uses feature that is not implemented\n");
        } else {
            fprintf(stderr, " ERROR obtaining verification result from the context\n");
        }
        goto end;
    }

    // print results
    printf(" VERIFICATION RESULTS\n");

    if (result == VERIFY_SUCCESS) {
        printf("     status: verification successful\n");
        ret_code = 0;
    } else {
        printf("     status: verification failed\n");
    }

end:
    if (sgl != NULL)
        sigil_free(&sgl);

    return ret_code;
}
 No newline at end of file