static void testOnlyStrongestProofReturned(CuTest* tc) { int res; KSI_Signature *sig1 = NULL; KSI_Signature *sig2 = NULL; KSI_Signature *sig3 = NULL; KSI_MultiSignature *ms = NULL; KSI_DataHash *hsh = NULL; KSI_PublicationRecord *publication = NULL; KSI_CalendarAuthRec *calAuth = NULL; KSI_ERR_clearErrors(ctx); res = KSI_MultiSignature_new(ctx, &ms); CuAssert(tc, "Unable to create multi signature container.", res == KSI_OK && ms != NULL); res = KSI_Signature_fromFile(ctx, getFullResourcePath(TEST_SIGNATURE_FILE), &sig1); CuAssert(tc, "Unable to read signature from file.", res == KSI_OK && sig1 != NULL); res = KSI_MultiSignature_add(ms, sig1); CuAssert(tc, "Unable to add signature to multi signature container.", res == KSI_OK); res = KSI_Signature_fromFile(ctx, getFullResourcePath(TEST_EX_SIGNATURE_FILE), &sig2); CuAssert(tc, "Unable to read signature from file.", res == KSI_OK && sig2 != NULL); res = KSI_MultiSignature_add(ms, sig2); CuAssert(tc, "Unable to add signature to multi signature container.", res == KSI_OK); res = KSI_Signature_getDocumentHash(sig1, &hsh); CuAssert(tc, "Unable to get signed hash value.", res == KSI_OK && hsh != NULL); res = KSI_MultiSignature_get(ms, hsh, &sig3); CuAssert(tc, "Unable to extract signature from multi signature container.", res == KSI_OK && sig3 != NULL); res = KSI_verifySignature(ctx, sig3); CuAssert(tc, "Unable to verify extracted signature.", res == KSI_OK); /* Verify the signature has a publication attached to it. */ res = KSI_Signature_getPublicationRecord(sig3, &publication); CuAssert(tc, "Publication must be present", res == KSI_OK && publication != NULL); /* Verify the signature does not contain a calendar authentication record. */ res = KSI_Signature_getCalendarAuthRec(sig3, &calAuth); CuAssert(tc, "Signature may not have a calendar auth record and a publication.", res == KSI_OK && calAuth == NULL); KSI_MultiSignature_free(ms); KSI_Signature_free(sig1); KSI_Signature_free(sig2); KSI_Signature_free(sig3); }
static void testDeleteSignatureAppendedFromFile(CuTest *tc, const char *fname) { int res; KSI_MultiSignature *ms = NULL; KSI_Signature *sig = NULL; KSI_HashAlgorithm *arr = NULL; KSI_DataHash *hsh = NULL; res = KSI_MultiSignature_new(ctx, &ms); CuAssert(tc, "Unable to create multi signature container.", res == KSI_OK && ms != NULL); res = KSI_Signature_fromFile(ctx, fname, &sig); CuAssert(tc, "Unable to read signature from file.", res == KSI_OK && sig != NULL); res = KSI_Signature_getDocumentHash(sig, &hsh); CuAssert(tc, "Unable to retrieve signed document hash from the signature.", res == KSI_OK && hsh != NULL); KSI_DataHash_ref(hsh); res = KSI_MultiSignature_add(ms, sig); CuAssert(tc, "Unable to add signature to multi signature container.", res == KSI_OK); KSI_Signature_free(sig); sig = NULL; res = KSI_MultiSignature_remove(ms, hsh); CuAssert(tc, "Unable to remove signature.", res == KSI_OK); res = KSI_MultiSignature_get(ms, hsh, &sig); CuAssert(tc, "There should not be a signature with this hash value anymore.", res == KSI_MULTISIG_NOT_FOUND && sig == NULL); /* TimeMapper list functions are not exported so we need to cast to generic list. */ CuAssert(tc, "The internal structure should be empty", KSI_List_length((KSI_List *)ms->timeList) == 0); KSI_MultiSignature_free(ms); KSI_DataHash_free(hsh); KSI_free(arr); }
static void testgetUsedHashAlgorithmsFromSingleLegacy(CuTest *tc) { int res; KSI_MultiSignature *ms = NULL; KSI_Signature *sig = NULL; KSI_HashAlgorithm *arr = NULL; size_t arr_len; res = KSI_MultiSignature_new(ctx, &ms); CuAssert(tc, "Unable to create multi signature container.", res == KSI_OK && ms != NULL); res = KSI_Signature_fromFile(ctx, getFullResourcePath("resource/tlv/ok-legacy-sig-2014-06.gtts.ksig"), &sig); CuAssert(tc, "Unable to read signature from file.", res == KSI_OK && sig != NULL); res = KSI_MultiSignature_add(ms, sig); CuAssert(tc, "Unable to add signature to multi signature container.", res == KSI_OK); KSI_Signature_free(sig); res = KSI_MultiSignature_getUsedHashAlgorithms(ms, &arr, &arr_len); CuAssert(tc, "Function should be successful", res == KSI_OK); CuAssert(tc, "Unexpected number of hash algorithms", arr_len == 1); CuAssert(tc, "If there are used algorithms, the output pointer should not be NULL", arr != NULL); CuAssert(tc, "Unexpected hash algorithm", arr[0] == KSI_HASHALG_SHA2_256); KSI_MultiSignature_free(ms); KSI_free(arr); }
static void Test_ExtendSignatureUsingAggregator(CuTest* tc) { int res = KSI_UNKNOWN_ERROR; KSI_Signature *sig = NULL; KSI_Signature *ext = NULL; KSI_CTX *ctx = NULL; /* Create the context. */ res = KSI_CTX_new(&ctx); CuAssert(tc, "Unable to create ctx.", res == KSI_OK && ctx != NULL); res = KSI_CTX_setPublicationUrl(ctx, conf.publications_file_url); CuAssert(tc, "Unable to set publications file url.", res == KSI_OK); res = KSI_CTX_setExtender(ctx, conf.aggregator_url, conf.aggregator_user, conf.aggregator_pass); CuAssert(tc, "Unable to set configure aggregator as extender.", res == KSI_OK); res = KSI_Signature_fromFile(ctx, getFullResourcePath("resource/tlv/ok-sig-2014-07-01.1.ksig"), &sig); CuAssert(tc, "Unable to set read signature from file.", res == KSI_OK && sig != NULL); res = KSI_Signature_extend(sig, ctx, NULL, &ext); CuAssert(tc, "The extending of signature must fail.", ext == NULL); CuAssert(tc, "Invalid KSI status code for mixed up request.", res == KSI_HTTP_ERROR); CuAssert(tc, "External error (HTTP) must be 400.", ctx_get_base_external_error(ctx) == 400); KSI_Signature_free(sig); KSI_Signature_free(ext); KSI_CTX_free(ctx); return; }
static void testExtractingNotExisting(CuTest* tc) { int res; KSI_Signature *sig = NULL; KSI_MultiSignature *ms = NULL; KSI_DataHash *hsh = NULL; KSI_ERR_clearErrors(ctx); res = KSI_Signature_fromFile(ctx, getFullResourcePath(TEST_SIGNATURE_FILE), &sig); CuAssert(tc, "Unable to read signature from file.", res == KSI_OK && sig != NULL); res = KSI_MultiSignature_new(ctx, &ms); CuAssert(tc, "Unable to create multi signature container.", res == KSI_OK && ms != NULL); res = KSI_MultiSignature_add(ms, sig); CuAssert(tc, "Unable to add signature to multi signature container.", res == KSI_OK); KSI_Signature_free(sig); sig = NULL; KSITest_DataHash_fromStr(ctx, "01db27c0db0aebb8d3963c3a720985cedb600f91854cdb1e45ad631611c39284dd", &hsh); res = KSI_MultiSignature_get(ms, hsh, &sig); CuAssert(tc, "Get should fail with KSI_MULTISIG_NOT_FOUND", res == KSI_MULTISIG_NOT_FOUND && sig == NULL); KSI_DataHash_free(hsh); KSI_MultiSignature_free(ms); KSI_Signature_free(sig); }
static void testVerifySignatureWithUserPublication(CuTest *tc) { int res; KSI_Signature *sig = NULL; const char pubStr[] = "AAAAAA-CTOQBY-AAMJYH-XZPM6T-UO6U6V-2WJMHQ-EJMVXR-JEAGID-2OY7P5-XFFKYI-QIF2LG-YOV7SO"; const char pubStr_bad[] = "AAAAAA-CT5VGY-AAPUCF-L3EKCC-NRSX56-AXIDFL-VZJQK4-WDCPOE-3KIWGB-XGPPM3-O5BIMW-REOVR4"; KSI_PublicationData *pubData = NULL; KSI_PublicationData *pubData_bad = NULL; KSI_ERR_clearErrors(ctx); res = KSI_PublicationData_fromBase32(ctx, pubStr, &pubData); CuAssert(tc, "Unable to parse publication string.", res == KSI_OK && pubData != NULL); res = KSI_PublicationData_fromBase32(ctx, pubStr_bad, &pubData_bad); CuAssert(tc, "Unable to parse publication string.", res == KSI_OK && pubData_bad != NULL); res = KSI_Signature_fromFile(ctx, getFullResourcePath("resource/tlv/ok-sig-2014-04-30.1-extended.ksig"), &sig); CuAssert(tc, "Unable to read signature from file.", res == KSI_OK && sig != NULL); res = KSI_Signature_verifyWithPublication(sig, ctx, pubData); CuAssert(tc, "Unable to verify signature with publication.", res == KSI_OK); res = KSI_Signature_verifyWithPublication(sig, ctx, pubData_bad); CuAssert(tc, "Unable to verify signature with publication.", res != KSI_OK); KSI_PublicationData_free(pubData); KSI_PublicationData_free(pubData_bad); KSI_Signature_free(sig); }
static void testSignatureWith2Anchors(CuTest *tc) { KSI_Signature *sig = NULL; int res; res = KSI_Signature_fromFile(ctx, getFullResourcePath("resource/tlv/nok-sig-two-anchors.tlv"), &sig); CuAssert(tc, "Reading a signature with more than one trust anchor should result in format error.", res == KSI_INVALID_FORMAT && sig == NULL); KSI_Signature_free(sig); }
static void testLoadSignatureFromFile(CuTest *tc) { int res; KSI_Signature *sig = NULL; KSI_ERR_clearErrors(ctx); res = KSI_Signature_fromFile(ctx, getFullResourcePath(TEST_SIGNATURE_FILE), &sig); CuAssert(tc, "Unable to read signature from file.", res == KSI_OK && sig != NULL); KSI_Signature_free(sig); }
static void createMultiSignature(KSI_MultiSignature **ms) { const char *signatures[] = {TEST_SIGNATURE_FILE, TEST_EX_SIGNATURE_FILE, NULL}; KSI_MultiSignature *tmp = NULL; KSI_Signature *sig = NULL; size_t i; KSI_MultiSignature_new(ctx, &tmp); for (i = 0; signatures[i] != NULL; i++) { KSI_Signature_fromFile(ctx, getFullResourcePath(signatures[i]), &sig); KSI_MultiSignature_add(tmp, sig); KSI_Signature_free(sig); } *ms = tmp; }
static void testVerifySignatureWithPublication(CuTest *tc) { int res; KSI_Signature *sig = NULL; KSI_ERR_clearErrors(ctx); res = KSI_Signature_fromFile(ctx, getFullResourcePath("resource/tlv/ok-sig-2014-04-30.1-extended.ksig"), &sig); CuAssert(tc, "Unable to read signature from file.", res == KSI_OK && sig != NULL); res = KSI_verifySignature(ctx, sig); CuAssert(tc, "Unable to verify signature with publication.", res == KSI_OK); KSI_Signature_free(sig); }
static void testVerifySignatureNew(CuTest *tc) { int res; KSI_Signature *sig = NULL; KSI_ERR_clearErrors(ctx); res = KSI_Signature_fromFile(ctx, getFullResourcePath(TEST_SIGNATURE_FILE), &sig); CuAssert(tc, "Unable to read signature from file.", res == KSI_OK && sig != NULL); /* Set the extend response. */ KSITest_setFileMockResponse(tc, getFullResourcePath("resource/tlv/ok-sig-2014-04-30.1-extend_response.tlv")); res = KSI_verifySignature(ctx, sig); CuAssert(tc, "Unable to verify signature online.", res == KSI_OK); KSI_Signature_free(sig); }
static void testSignerIdentity(CuTest *tc) { int res; const char id_expected[] = "GT :: testA :: 36-test"; KSI_Signature *sig = NULL; char *id_actual = NULL; res = KSI_Signature_fromFile(ctx, getFullResourcePath("resource/tlv/ok-sig-2014-08-01.1.ksig"), &sig); CuAssert(tc, "Unable to load signature", res == KSI_OK && sig != NULL); res = KSI_Signature_getSignerIdentity(sig, &id_actual); CuAssert(tc, "Unable to get signer identity from signature.", res == KSI_OK && id_actual != NULL); CuAssert(tc, "Unexpected signer identity", !strncmp(id_expected, id_actual, strlen(id_expected))); KSI_Signature_free(sig); KSI_free(id_actual); }
static void Test_OKExtendSignatureDefProvider(CuTest* tc) { int res; KSI_Signature *sig = NULL; KSI_Signature *ext = NULL; res = KSI_Signature_fromFile(ctx, getFullResourcePath("resource/tlv/ok-sig-2014-07-01.1.ksig"), &sig); CuAssert(tc, "Unable to read signature frome file.", res == KSI_OK && sig != NULL); res = KSI_Signature_extend(sig, ctx, NULL, &ext); CuAssert(tc, "Unable to extend signature", res == KSI_OK && ext != NULL); res = KSI_verifySignature(ctx, sig); CuAssert(tc, "Unable to verify signature", res == KSI_OK); KSI_ERR_clearErrors(ctx); KSI_Signature_free(sig); KSI_Signature_free(ext); }
static void testSignatureSigningTime(CuTest *tc) { int res; KSI_Signature *sig = NULL; KSI_Integer *sigTime = NULL; KSI_uint64_t utc = 0; KSI_ERR_clearErrors(ctx); res = KSI_Signature_fromFile(ctx, getFullResourcePath(TEST_SIGNATURE_FILE), &sig); CuAssert(tc, "Unable to read signature from file.", res == KSI_OK && sig != NULL); res = KSI_Signature_getSigningTime(sig, &sigTime); CuAssert(tc, "Unable to get signing time from signature", res == KSI_OK && sigTime != NULL); utc = KSI_Integer_getUInt64(sigTime); CuAssert(tc, "Unexpected signature signing time.", utc == 1398866256); KSI_Signature_free(sig); }
static void testAddingSingle(CuTest* tc) { int res; KSI_Signature *sig = NULL; KSI_MultiSignature *ms = NULL; KSI_ERR_clearErrors(ctx); res = KSI_Signature_fromFile(ctx, getFullResourcePath(TEST_SIGNATURE_FILE), &sig); CuAssert(tc, "Unable to read signature from file.", res == KSI_OK && sig != NULL); res = KSI_MultiSignature_new(ctx, &ms); CuAssert(tc, "Unable to create multi signature container.", res == KSI_OK && ms != NULL); res = KSI_MultiSignature_add(ms, sig); CuAssert(tc, "Unable to add signature to multi signature container.", res == KSI_OK); KSI_MultiSignature_free(ms); KSI_Signature_free(sig); }
static void testVerifySignatureExtendedToHead(CuTest *tc) { int res; KSI_Signature *sig = NULL; KSI_ERR_clearErrors(ctx); res = KSI_Signature_fromFile(ctx, getFullResourcePath("resource/tlv/ok-sig-2014-04-30.1-head.ksig"), &sig); CuAssert(tc, "Signature should have either a calendar auth record or publication", res == KSI_OK && sig != NULL); /* Set the extend response. */ KSITest_setFileMockResponse(tc, getFullResourcePath("resource/tlv/ok-sig-2014-04-30.1-head-extend_response.tlv")); ctx->requestCounter = 0; res = KSI_Signature_verifyOnline(sig, ctx); CuAssert(tc, "Signature should verify", res == KSI_OK); KSI_Signature_free(sig); }
static void Test_ExtendSignature_useProvider(CuTest* tc, const char *uri_host, unsigned port, const char *user, const char *key, const char *pub_uri, int (*createProvider)(KSI_CTX *ctx, KSI_NetworkClient **http), int (*setPubfail)(KSI_NetworkClient *client, const char *url), int (*setExtender)(KSI_NetworkClient *client, const char *url_host, unsigned port, const char *user, const char *pass)) { int res = KSI_UNKNOWN_ERROR; KSI_Signature *sig = NULL; KSI_Signature *ext = NULL; KSI_NetworkClient *client = NULL; KSI_CTX *ctx = NULL; /* Create the context. */ res = KSI_CTX_new(&ctx); CuAssert(tc, "Unable to create ctx.", res == KSI_OK && ctx != NULL); res = createProvider(ctx, &client); CuAssert(tc, "Unable to create network client.", res == KSI_OK && client != NULL); res = setExtender(client, uri_host, port, user, key); CuAssert(tc, "Unable to set extender specific service information.", res == KSI_OK); res = setPubfail(client, pub_uri); CuAssert(tc, "Unable to set publications file url.", res == KSI_OK); res = KSI_CTX_setNetworkProvider(ctx, client); CuAssert(tc, "Unable to set new network client.", res == KSI_OK); client = NULL; res = KSI_Signature_fromFile(ctx, getFullResourcePath("resource/tlv/ok-sig-2014-07-01.1.ksig"), &sig); CuAssert(tc, "Unable to set read signature from file.", res == KSI_OK && sig != NULL); res = KSI_Signature_extend(sig, ctx, NULL, &ext); CuAssert(tc, "The extending of signature must not fail.", res == KSI_OK && ext != NULL); KSI_NetworkClient_free(client); KSI_Signature_free(sig); KSI_Signature_free(ext); KSI_CTX_free(ctx); return; }
static void testExtractingSingleLegacy(CuTest* tc) { int res; KSI_Signature *sig = NULL; KSI_MultiSignature *ms = NULL; KSI_DataHash *hsh = NULL; KSI_ERR_clearErrors(ctx); res = KSI_Signature_fromFile(ctx, getFullResourcePath("resource/tlv/ok-legacy-sig-2014-06.gtts.ksig"), &sig); CuAssert(tc, "Unable to read signature from file.", res == KSI_OK && sig != NULL); res = KSI_Signature_getDocumentHash(sig, &hsh); CuAssert(tc, "Unable to get signed hash value.", res == KSI_OK && hsh != NULL); KSI_DataHash_ref(hsh); res = KSI_MultiSignature_new(ctx, &ms); CuAssert(tc, "Unable to create multi signature container.", res == KSI_OK && ms != NULL); res = KSI_MultiSignature_add(ms, sig); CuAssert(tc, "Unable to add signature to multi signature container.", res == KSI_OK); KSI_Signature_free(sig); sig = NULL; res = KSI_MultiSignature_get(ms, hsh, &sig); CuAssert(tc, "Unable to extract signature from multi signature container.", res == KSI_OK && sig != NULL); res = KSI_verifySignature(ctx, sig); CuAssert(tc, "Unable to verify extracted signature.", res == KSI_OK); KSI_DataHash_free(hsh); KSI_MultiSignature_free(ms); KSI_Signature_free(sig); }
int main(int argc, char **argv) { KSI_CTX *ksi = NULL; int res; FILE *out = NULL; KSI_Signature *sig = NULL; KSI_Signature *ext = NULL; KSI_HttpClient *net = NULL; unsigned char *raw = NULL; unsigned raw_len; unsigned count; FILE *logFile = NULL; if (argc != 5) { printf("Usage:\n" " %s <signature> <extended> <extender uri> <pub-file uri| ->\n", argv[0]); res = KSI_INVALID_ARGUMENT; goto cleanup; } /* Init KSI context */ res = KSI_CTX_new(&ksi); if (res != KSI_OK) { fprintf(stderr, "Unable to init KSI context.\n"); goto cleanup; } logFile = fopen("ksi_extend.log", "w"); if (logFile == NULL) { fprintf(stderr, "Unable to open log file.\n"); } KSI_CTX_setLoggerCallback(ksi, KSI_LOG_StreamLogger, logFile); KSI_CTX_setLogLevel(ksi, KSI_LOG_DEBUG); KSI_LOG_info(ksi, "Using KSI version: '%s'", KSI_getVersion()); res = KSI_HttpClient_new(ksi, &net); if (res != KSI_OK) { fprintf(stderr, "Unable to create new network provider.\n"); goto cleanup; } res = KSI_HttpClient_setExtender(net, argv[3], "anon", "anon"); if (res != KSI_OK) goto cleanup; if (strcmp(argv[4], "-")) { res = KSI_HttpClient_setPublicationUrl(net, argv[4]); if (res != KSI_OK) goto cleanup; } res = KSI_CTX_setNetworkProvider(ksi, (KSI_NetworkClient *)net); if (res != KSI_OK) { fprintf(stderr, "Unable to set new network provider.\n"); goto cleanup; } /* Read the signature. */ res = KSI_Signature_fromFile(ksi, argv[1], &sig); if (res != KSI_OK) { KSI_ERR_statusDump(ksi, stdout); fprintf(stderr, "Unable to read signature from '%s'\n", argv[1]); goto cleanup; } /* Make sure the signature is ok. */ res = KSI_verifySignature(ksi, sig); if (res != KSI_OK) { fprintf(stderr, "Unable to verify signature.\n"); KSI_ERR_statusDump(ksi, stderr); goto cleanup; } /* Extend the signature. */ res = KSI_extendSignature(ksi, sig, &ext); if (res != KSI_OK) { if (res == KSI_EXTEND_NO_SUITABLE_PUBLICATION) { printf("No suitable publication to extend to.\n"); goto cleanup; } fprintf(stderr, "Unable to extend signature.\n"); KSI_ERR_statusDump(ksi, stderr); goto cleanup; } /* To be extra sure, lets verify the extended signature. */ res = KSI_verifySignature(ksi, ext); if (res != KSI_OK) { fprintf(stderr, "Unable to verify the extended signature.\n"); KSI_ERR_statusDump(ksi, stderr); goto cleanup; } /* Serialize the extended signature. */ res = KSI_Signature_serialize(ext, &raw, &raw_len); if (res != KSI_OK) { fprintf(stderr, "Unable to serialize extended signature.\n"); goto cleanup; } /* Open output file. */ out = fopen(argv[2], "wb"); if (out == NULL) { fprintf(stderr, "Unable to open output file '%s'\n", argv[2]); res = KSI_IO_ERROR; goto cleanup; } count = (unsigned)fwrite(raw, 1, raw_len, out); if (count != raw_len) { fprintf(stderr, "Failed to write output file.\n"); res = KSI_IO_ERROR; goto cleanup; } printf("Signature extended."); cleanup: if (logFile != NULL) fclose(logFile); if (out != NULL) fclose(out); KSI_Signature_free(sig); KSI_Signature_free(ext); KSI_free(raw); KSI_CTX_free(ksi); return res; }
int main(int argc, char **argv) { int res = KSI_UNKNOWN_ERROR; /* Signature read from the file. */ KSI_Signature *sig = NULL; /* Signature extended to the publication. */ KSI_Signature *ext = NULL; /* Hash of the data file. */ KSI_DataHash *hsh = NULL; /* Hash value extracted from the signature. */ KSI_DataHash *signHsh = NULL; /* Data file hasher. */ KSI_DataHasher *hsr = NULL; /* Input file descriptor. */ FILE *in = NULL; /* Buffer for reading the input. */ unsigned char buf[1024]; /* Length of the buffer content. */ size_t buf_len; /* Verification info object. */ const KSI_VerificationResult *info = NULL; /* File descriptor for logging. */ FILE *logFile = NULL; const KSI_CertConstraint pubFileCertConstr[] = { { KSI_CERT_EMAIL, "*****@*****.**"}, { NULL, NULL } }; /* Init context. */ res = KSI_CTX_new(&ksi); if (res != KSI_OK) { fprintf(stderr, "Unable to init KSI context.\n"); goto cleanup; } logFile = fopen("ksi_verify.log", "w"); if (logFile == NULL) { fprintf(stderr, "Unable to open log file.\n"); } res = KSI_CTX_setDefaultPubFileCertConstraints(ksi, pubFileCertConstr); if (res != KSI_OK) { fprintf(stderr, "Unable to configure publications file cert constraints.\n"); goto cleanup; } /* Configure the logger. */ KSI_CTX_setLoggerCallback(ksi, KSI_LOG_StreamLogger, logFile); KSI_CTX_setLogLevel(ksi, KSI_LOG_DEBUG); KSI_LOG_info(ksi, "Using KSI version: '%s'", KSI_getVersion()); /* Check parameters. */ if (argc != 6) { fprintf(stderr, "Usage\n" " %s <data file | -> <signature> <publication-str> <extender url> <pub-file url>\n", argv[0]); goto cleanup; } /* Configure extender. */ res = KSI_CTX_setExtender(ksi, argv[4], "anon", "anon"); if (res != KSI_OK) { fprintf(stderr, "Unable to set extender parameters.\n"); goto cleanup; } /* Set the publications file url. */ res = KSI_CTX_setPublicationUrl(ksi, argv[4]); if (res != KSI_OK) { fprintf(stderr, "Unable to set publications file url.\n"); goto cleanup; } printf("Reading signature... "); /* Read the signature. */ res = KSI_Signature_fromFile(ksi, argv[2], &sig); if (res != KSI_OK) { printf("failed (%s)\n", KSI_getErrorString(res)); goto cleanup; } printf("ok\n"); printf("Verifying the signature with the publication... "); res = extendToPublication(sig, argv[3], &ext); switch (res) { case KSI_OK: printf("ok\n"); break; case KSI_VERIFICATION_FAILURE: printf("failed\n"); break; default: printf("failed (%s)\n", KSI_getErrorString(res)); goto cleanup; } /* Create hasher. */ res = KSI_Signature_createDataHasher(ext, &hsr); if (res != KSI_OK) { fprintf(stderr, "Unable to create data hasher.\n"); goto cleanup; } if (strcmp(argv[1], "-")) { in = fopen(argv[1], "rb"); if (in == NULL) { fprintf(stderr, "Unable to open data file '%s'.\n", argv[1]); goto cleanup; } /* Calculate the hash of the document. */ while (!feof(in)) { buf_len = fread(buf, 1, sizeof(buf), in); res = KSI_DataHasher_add(hsr, buf, buf_len); if (res != KSI_OK) { fprintf(stderr, "Unable hash the document.\n"); goto cleanup; } } /* Finalize the hash computation. */ res = KSI_DataHasher_close(hsr, &hsh); if (res != KSI_OK) { fprintf(stderr, "Failed to close the hashing process.\n"); goto cleanup; } res = KSI_Signature_getDocumentHash(sig, &signHsh); if (res != KSI_OK) goto cleanup; printf("Verifying document hash... "); if (!KSI_DataHash_equals(hsh, signHsh)) { printf("Wrong document!\n"); goto cleanup; } printf("ok\n"); } res = KSI_Signature_getVerificationResult(ext, &info); if (res != KSI_OK) goto cleanup; if (info != NULL) { size_t i; printf("Verification info:\n"); for (i = 0; i < KSI_VerificationResult_getStepResultCount(info); i++) { const KSI_VerificationStepResult *result = NULL; const char *desc = NULL; res = KSI_VerificationResult_getStepResult(info, i, &result); if (res != KSI_OK) goto cleanup; printf("\t0x%02x:\t%s", KSI_VerificationStepResult_getStep(result), KSI_VerificationStepResult_isSuccess(result) ? "OK" : "FAIL"); desc = KSI_VerificationStepResult_getDescription(result); if (desc && *desc) { printf(" (%s)", desc); } printf("\n"); } } res = KSI_OK; cleanup: if (logFile != NULL) fclose(logFile); if (res != KSI_OK && ksi != NULL) { KSI_ERR_statusDump(ksi, stderr); } if (in != NULL) fclose(in); KSI_Signature_free(sig); KSI_Signature_free(ext); KSI_DataHasher_free(hsr); KSI_DataHash_free(hsh); KSI_CTX_free(ksi); return res; }