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 testFindPublicationByPubStr(CuTest *tc) { static const char publication[] = "AAAAAA-CTJR3I-AANBWU-RY76YF-7TH2M5-KGEZVA-WLLRGD-3GKYBG-AM5WWV-4MCLSP-XPRDDI-UFMHBA"; int res; KSI_PublicationsFile *pubFile = NULL; KSI_PublicationRecord *pubRec = NULL; KSI_PublicationData *pub = NULL; KSI_DataHash *pubHsh = NULL; KSI_Integer *pubTime = NULL; KSI_DataHash *expHsh = NULL; unsigned char buf[0xff]; size_t len; KSI_CTX *ctx = NULL; res = KSITest_CTX_clone(&ctx); CuAssert(tc, "Unable to create KSI context.", res == KSI_OK && ctx != NULL); res = KSITest_setDefaultPubfileAndVerInfo(ctx); CuAssert(tc, "Unable to set default values to context.", res == KSI_OK); KSI_ERR_clearErrors(ctx); res = KSI_CTX_setPublicationUrl(ctx, getFullResourcePathUri(TEST_PUBLICATIONS_FILE)); CuAssert(tc, "Unable to set pubfile URI.", res == KSI_OK); res = KSI_receivePublicationsFile(ctx, &pubFile); CuAssert(tc, "Unable to get publications file.", res == KSI_OK && pubFile != NULL); res = KSI_verifyPublicationsFile(ctx, pubFile); CuAssert(tc, "Unable to verify publications file.", res == KSI_OK); res = KSI_PublicationsFile_getPublicationDataByPublicationString(pubFile, publication, &pubRec); CuAssert(tc, "Unable to get publication record by publication string.", res == KSI_OK && pubRec != NULL); res = KSI_PublicationRecord_getPublishedData(pubRec, &pub); CuAssert(tc, "Unable to get published data", res == KSI_OK && pub != NULL); res = KSI_PublicationData_getImprint(pub, &pubHsh); CuAssert(tc, "Unable to get published hash", res == KSI_OK && pubHsh != NULL); res = KSI_PublicationData_getTime(pub, &pubTime); CuAssert(tc, "Unable to get publication time.", res == KSI_OK && pubTime != NULL); KSITest_decodeHexStr("01a1b5238ffb05fccfa67546266a0b2d7130f6656026033b6b578c12e4fbbe231a", buf, sizeof(buf), &len); res = KSI_DataHash_fromImprint(ctx, buf, len, &expHsh); CuAssert(tc, "Unable to get data hash from imprint.", res == KSI_OK && expHsh != NULL); CuAssert(tc, "Publication hash mismatch.", KSI_DataHash_equals(expHsh, pubHsh)); CuAssert(tc, "Publication time mismatch", KSI_Integer_equalsUInt(pubTime, 1397520000)); KSI_DataHash_free(expHsh); KSI_PublicationsFile_free(pubFile); KSI_CTX_free(ctx); }
static void testFindPublicationRef(CuTest *tc) { int res; KSI_PublicationsFile *pubFile = NULL; KSI_PublicationRecord *pubRec = NULL; KSI_Integer *pubTime = NULL; KSI_LIST(KSI_Utf8String) *pubRefList = NULL; size_t i; int isPubRefFound = 0; KSI_CTX *ctx = NULL; res = KSITest_CTX_clone(&ctx); CuAssert(tc, "Unable to create KSI context.", res == KSI_OK && ctx != NULL); res = KSITest_setDefaultPubfileAndVerInfo(ctx); CuAssert(tc, "Unable to set default values to context.", res == KSI_OK); KSI_ERR_clearErrors(ctx); res = KSI_CTX_setPublicationUrl(ctx, getFullResourcePathUri(TEST_PUBLICATIONS_FILE)); CuAssert(tc, "Unable to set pubfile URI.", res == KSI_OK); res = KSI_receivePublicationsFile(ctx, &pubFile); CuAssert(tc, "Unable to get publications file.", res == KSI_OK && pubFile != NULL); res = KSI_verifyPublicationsFile(ctx, pubFile); CuAssert(tc, "Unable to verify publications file.", res == KSI_OK); res = KSI_Integer_new(ctx, 1397520000, &pubTime); CuAssert(tc, "Unable to create ksi integer object.", res == KSI_OK && pubTime != NULL); res = KSI_PublicationsFile_getPublicationDataByTime(pubFile, pubTime, &pubRec); CuAssert(tc, "Unable to get publication record by publication date.", res == KSI_OK && pubRec != NULL); KSI_Integer_free(pubTime); pubTime = NULL; res = KSI_PublicationRecord_getPublicationRefList(pubRec, &pubRefList); CuAssert(tc, "Unable to get publications ref list", res == KSI_OK && pubRefList != NULL); for (i = 0; i < KSI_Utf8StringList_length(pubRefList); i++) { KSI_Utf8String *pubRef = NULL; res = KSI_Utf8StringList_elementAt(pubRefList, i, &pubRef); CuAssert(tc, "Unable to get element from list", res == KSI_OK && pubRef != NULL); if (!strcmp("Financial Times, ISSN: 0307-1766, 2014-04-17", KSI_Utf8String_cstr(pubRef))) { isPubRefFound = 1; } } CuAssert(tc, "Financial times publication not found", isPubRefFound); KSI_PublicationsFile_free(pubFile); KSI_CTX_free(ctx); }
static void testReceivePublicationsFileInvalidPki(CuTest *tc) { int res; KSI_PublicationsFile *pubFile = NULL; KSI_PKITruststore *pki = NULL; KSI_CertConstraint arr[] = { {KSI_CERT_EMAIL, "*****@*****.**"}, {NULL, NULL} }; KSI_CTX *ctx = NULL; res = KSITest_CTX_clone(&ctx); CuAssert(tc, "Unable to create new context.", res == KSI_OK && ctx != NULL); KSI_ERR_clearErrors(ctx); res = KSI_CTX_setPublicationUrl(ctx, getFullResourcePathUri(TEST_PUBLICATIONS_FILE_INVALID_PKI)); CuAssert(tc, "Unable to clear pubfile URI.", res == KSI_OK); /* Configure expected PIK cert and constraints for pub. file. */ res = KSI_PKITruststore_new(ctx, 0, &pki); CuAssert(tc, "Unable to get PKI truststore from context.", res == KSI_OK && pki != NULL); res = KSI_CTX_setPKITruststore(ctx, pki); CuAssert(tc, "Unable to set new pki truststrore for ksi context.", res == KSI_OK); res = KSI_PKITruststore_addLookupFile(pki, getFullResourcePath("resource/tlv/mock.crt")); CuAssert(tc, "Unable to read certificate", res == KSI_OK); res = KSI_CTX_setDefaultPubFileCertConstraints(ctx, arr); CuAssert(tc, "Unable to set OID 2.5.4.10", res == KSI_OK); res = KSI_receivePublicationsFile(ctx, &pubFile); CuAssert(tc, "Unable to receive publications file.", res == KSI_OK && pubFile != NULL); res = KSI_verifyPublicationsFile(ctx, pubFile); CuAssert(tc, "Publications file should NOT verify as PKI signature is wrong.", res == KSI_INVALID_PKI_SIGNATURE); KSI_PublicationsFile_free(pubFile); KSI_CTX_free(ctx); }
int main(int argc, char **argv) { KSI_CTX *ksi = NULL; int res = KSI_UNKNOWN_ERROR; FILE *in = NULL; FILE *out = NULL; KSI_DataHasher *hsr = NULL; KSI_DataHash *hsh = NULL; KSI_Signature *sign = NULL; unsigned char *raw = NULL; unsigned raw_len; unsigned char buf[1024]; unsigned buf_len; char *signerIdentity = NULL; FILE *logFile = NULL; /* Handle command line parameters */ /* Handle command line parameters */ if (argc != 7) { fprintf(stderr, "Usage:\n" " %s <in-data-file> <out-sign-file> <aggregator-uri> <user> <pass> <pub-file url | -> \n", argv[0]); res = KSI_INVALID_ARGUMENT; goto cleanup; } /* Input file */ in = fopen(argv[1], "rb"); if (in == NULL) { fprintf(stderr, "Unable to open input file '%s'\n", argv[1]); res = KSI_IO_ERROR; goto cleanup; } /* Create new KSI context for this thread. */ res = KSI_CTX_new(&ksi); if (res != KSI_OK) { fprintf(stderr, "Unable to create context.\n"); goto cleanup; } logFile = fopen("ksi_sign.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_CTX_setAggregator(ksi, argv[3], argv[4], argv[5]); if (res != KSI_OK) goto cleanup; /* Check publications file url. */ if (strncmp("-", argv[6], 1)) { res = KSI_CTX_setPublicationUrl(ksi, argv[6]); if (res != KSI_OK) { fprintf(stderr, "Unable to set publications file url.\n"); goto cleanup; } } /* Create a data hasher using default algorithm. */ res = KSI_DataHasher_open(ksi, KSI_getHashAlgorithmByName("default"), &hsr); if (res != KSI_OK) { fprintf(stderr, "Unable to create hasher.\n"); goto cleanup; } /* Read the input file and calculate the hash of its contents. */ while (!feof(in)) { buf_len = (unsigned)fread(buf, 1, sizeof(buf), in); /* Add next block to the calculation. */ res = KSI_DataHasher_add(hsr, buf, buf_len); if (res != KSI_OK) { fprintf(stderr, "Unable to add data to hasher.\n"); goto cleanup; } } /* Close the data hasher and retreive the data hash. */ res = KSI_DataHasher_close(hsr, &hsh); if (res != KSI_OK) { fprintf(stderr, "Unable to create hash.\n"); goto cleanup; } /* Sign the data hash. */ res = KSI_createSignature(ksi, hsh, &sign); if (res != KSI_OK) { fprintf(stderr, "Unable to sign %d.\n", res); goto cleanup; } res = KSI_Signature_verify(sign, ksi); if (res != KSI_OK) { fprintf(stderr, "Failed to verify signature.\n"); goto cleanup; } /* Output the signer id */ res = KSI_Signature_getSignerIdentity(sign, &signerIdentity); if (res == KSI_OK) { printf("Signer id: %s\n", signerIdentity); } else { fprintf(stderr, "Unable to extract signer identity.\n"); } /* Serialize the signature. */ res = KSI_Signature_serialize(sign, &raw, &raw_len); if (res != KSI_OK) { fprintf(stderr, "Unable to serialize signature."); goto cleanup; } /* Output file */ out = fopen(argv[2], "wb"); if (out == NULL) { fprintf(stderr, "Unable to open input file '%s'\n", argv[2]); res = KSI_IO_ERROR; goto cleanup; } /* Write the signature file. */ if (!fwrite(raw, 1, raw_len, out)) { fprintf(stderr, "Unable to write output file.\n"); res = KSI_IO_ERROR; goto cleanup; } /* Only print message when signature output is not stdout. */ if (out != NULL) { printf("Signature saved.\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); if (out != NULL) fclose(out); KSI_free(signerIdentity); KSI_Signature_free(sign); KSI_DataHash_free(hsh); KSI_DataHasher_free(hsr); KSI_free(raw); KSI_CTX_free(ksi); return res; }
int main(int argc, char **argv) { KSI_CTX *ksi = NULL; int res; FILE *out = NULL; KSI_Signature *sig = NULL; KSI_Signature *ext = NULL; unsigned char *raw = NULL; size_t raw_len; unsigned count; FILE *logFile = NULL; const KSI_CertConstraint pubFileCertConstr[] = { { KSI_CERT_EMAIL, "*****@*****.**"}, { NULL, NULL } }; if (argc != 5) { printf("Usage:\n" " %s <signature> <extended> <extender uri> <pub-file url>\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"); } res = KSI_CTX_setDefaultPubFileCertConstraints(ksi, pubFileCertConstr); if (res != KSI_OK) { fprintf(stderr, "Unable to configure publications file cert constraints.\n"); goto cleanup; } 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_CTX_setExtender(ksi, argv[3], "anon", "anon"); if (res != KSI_OK) goto cleanup; res = KSI_CTX_setPublicationUrl(ksi, argv[4]); if (res != KSI_OK) 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; }
static void testFindPublicationByTime(CuTest *tc) { int res; KSI_PublicationsFile *pubFile = NULL; KSI_PublicationRecord *pubRec = NULL; KSI_PublicationData *pub = NULL; KSI_DataHash *pubHsh = NULL; KSI_Integer *pubTime = NULL; KSI_DataHash *expHsh = NULL; KSI_LIST(KSI_Utf8String) *pubRefList = NULL; unsigned char buf[0xff]; size_t len; KSI_CTX *ctx = NULL; res = KSITest_CTX_clone(&ctx); CuAssert(tc, "Unable to create KSI context.", res == KSI_OK && ctx != NULL); res = KSITest_setDefaultPubfileAndVerInfo(ctx); CuAssert(tc, "Unable to set default values to context.", res == KSI_OK); KSI_ERR_clearErrors(ctx); res = KSI_CTX_setPublicationUrl(ctx, getFullResourcePathUri(TEST_PUBLICATIONS_FILE)); CuAssert(tc, "Unable to set pubfile URI.", res == KSI_OK); res = KSI_receivePublicationsFile(ctx, &pubFile); CuAssert(tc, "Unable to get publications file.", res == KSI_OK && pubFile != NULL); res = KSI_verifyPublicationsFile(ctx, pubFile); CuAssert(tc, "Unable to verify publications file.", res == KSI_OK); res = KSI_Integer_new(ctx, 1397520000, &pubTime); CuAssert(tc, "Unable to create ksi integer object.", res == KSI_OK && pubTime != NULL); res = KSI_PublicationsFile_getPublicationDataByTime(pubFile, pubTime, &pubRec); CuAssert(tc, "Unable to get publication record by publication date.", res == KSI_OK && pubRec != NULL); res = KSI_PublicationRecord_getPublishedData(pubRec, &pub); CuAssert(tc, "Unable to get published data", res == KSI_OK && pub != NULL); res = KSI_PublicationData_getImprint(pub, &pubHsh); CuAssert(tc, "Unable to get published hash", res == KSI_OK && pubHsh != NULL); KSI_Integer_free(pubTime); pubTime = NULL; res = KSI_PublicationData_getTime(pub, &pubTime); CuAssert(tc, "Unable to get publication time.", res == KSI_OK && pubTime != NULL); KSITest_decodeHexStr("01a1b5238ffb05fccfa67546266a0b2d7130f6656026033b6b578c12e4fbbe231a", buf, sizeof(buf), &len); res = KSI_DataHash_fromImprint(ctx, buf, len, &expHsh); CuAssert(tc, "Unable to get datahash from imprint", res == KSI_OK && expHsh != NULL); CuAssert(tc, "Publication hash mismatch.", KSI_DataHash_equals(expHsh, pubHsh)); CuAssert(tc, "Publication time mismatch", KSI_Integer_equalsUInt(pubTime, 1397520000)); res = KSI_PublicationRecord_getPublicationRefList(pubRec, &pubRefList); CuAssert(tc, "Unable to get publications ref list", res == KSI_OK && pubRefList != NULL); KSI_DataHash_free(expHsh); KSI_PublicationsFile_free(pubFile); KSI_CTX_free(ctx); }
int main(int argc, char **argv) { KSI_CTX *ksi = NULL; int res = KSI_UNKNOWN_ERROR; KSI_DataHash *hsh = NULL; KSI_RequestHandle *handle[REQUESTS]; KSI_NetworkClient *http = NULL; FILE *logFile = NULL; size_t i; KSI_DataHasher *hsr = NULL; const KSI_CertConstraint pubFileCertConstr[] = { { KSI_CERT_EMAIL, "*****@*****.**"}, { NULL, NULL } }; struct { size_t ok; size_t nok; } stat; stat.ok = 0; stat.nok = 0; /* Create new KSI context for this thread. */ res = KSI_CTX_new(&ksi); if (res != KSI_OK) { fprintf(stderr, "Unable to create context.\n"); goto cleanup; } 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. */ res = OpenLogging(ksi, "multi_curl.log", &logFile); if (res != KSI_OK) goto cleanup; KSI_LOG_info(ksi, "Using KSI version: '%s'", KSI_getVersion()); /* Check publications file url. */ res = KSI_CTX_setPublicationUrl(ksi, "http://verify.guardtime.com/ksi-publications.bin"); if (res != KSI_OK) { fprintf(stderr, "Unable to set publications file url.\n"); goto cleanup; } res = KSI_HttpClient_new(ksi, &http); if (res != KSI_OK) { fprintf(stderr, "Unable to create http client.\n"); goto cleanup; } res = KSI_HttpClient_setAggregator(http, "http://ksigw.test.guardtime.com:3332", "anon", "anon"); if (res != KSI_OK) { fprintf(stderr, "Unable to set aggregator url.\n"); goto cleanup; } KSI_HttpClient_setReadTimeoutSeconds(http, 10); KSI_HttpClient_setConnectTimeoutSeconds(http, 10); for (i = 0; i < REQUESTS; i++) { char buf[100]; size_t len; KSI_AggregationReq *req = NULL; len = KSI_snprintf(buf, sizeof(buf), "Hello %d", i); res = KSI_DataHash_create(ksi, buf, len, KSI_getHashAlgorithmByName("default"), &hsh); if (res != KSI_OK) { fprintf(stderr, "Unable to create hash."); goto cleanup; } res = KSI_AggregationReq_new(ksi, &req); if (res != KSI_OK) { fprintf(stderr, "Unable to create request."); goto cleanup; } res = KSI_AggregationReq_setRequestHash(req, hsh); if (res != KSI_OK) { fprintf(stderr, "Unable to set request hash."); goto cleanup; } res = KSI_NetworkClient_sendSignRequest(http, req, &handle[i]); if (res != KSI_OK) { fprintf(stderr, "Unable to send aggregation request."); goto cleanup; } KSI_AggregationReq_free(req); } res = KSI_NetworkClient_performAll(http, handle, REQUESTS); if (res != KSI_OK) { fprintf(stderr, "Unable to perform requests."); goto cleanup; } for (i = 0; i < REQUESTS; i++) { KSI_AggregationResp *resp = NULL; res = KSI_RequestHandle_getAggregationResponse(handle[i], &resp); if (res != KSI_OK) { const KSI_RequestHandleStatus *st = NULL; res = KSI_RequestHandle_getResponseStatus(handle[i], &st); if (res == KSI_OK) { printf("Status code = %ld: %s\n", st->code, st->errm); } KSI_ERR_statusDump(ksi, stdout); stat.nok++; } else { stat.ok ++; } KSI_AggregationResp_free(resp); } printf("Requests:\n" " Successful: %llu\n" " Failed: %llu\n" " TOTAL: %llu\n", (unsigned long long)stat.ok, (unsigned long long)stat.nok, (unsigned long long)(stat.ok + stat.nok)); res = KSI_OK; cleanup: if (logFile != NULL) fclose(logFile); if (res != KSI_OK && ksi != NULL) { KSI_ERR_statusDump(ksi, stderr); } KSI_DataHash_free(hsh); KSI_DataHasher_free(hsr); 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; }