static void testGetNearestPublicationWithPubTime(CuTest *tc) { int res; KSI_PublicationsFile *pubFile = NULL; KSI_PublicationRecord *pubRec = NULL; KSI_Integer *tm = NULL; KSI_PublicationData *pubDat = NULL; KSI_Integer *pubTm = NULL; res = KSI_PublicationsFile_fromFile(ctx, getFullResourcePath(TEST_PUBLICATIONS_FILE), &pubFile); CuAssert(tc, "Unable to read publications file", res == KSI_OK && pubFile != NULL); /* With time set to 0, the result should be the first publication record in the publications file. */ res = KSI_Integer_new(ctx, 1208217600, &tm); CuAssert(tc, "Unable to create integer", res == KSI_OK && tm != NULL); res = KSI_PublicationsFile_getNearestPublication(pubFile, tm, &pubRec); CuAssert(tc, "Unable to find nearest publication", res == KSI_OK && pubRec != NULL); res = KSI_PublicationRecord_getPublishedData(pubRec, &pubDat); CuAssert(tc, "Unable to get published data", res == KSI_OK && pubDat != NULL); res = KSI_PublicationData_getTime(pubDat, &pubTm); CuAssert(tc, "Unable to get publication time", res == KSI_OK && pubTm != NULL); CuAssert(tc, "Unexpected publication time", KSI_Integer_equalsUInt(pubTm, 1208217600)); KSI_PublicationRecord_free(pubRec); KSI_PublicationsFile_free(pubFile); KSI_Integer_free(tm); }
static void testGetLatestPublicationOfLast(CuTest *tc) { int res; KSI_PublicationsFile *pubFile = NULL; KSI_PublicationRecord *pubRec = NULL; KSI_Integer *tm = NULL; KSI_PublicationData *pubDat = NULL; KSI_Integer *pubTm = NULL; res = KSI_PublicationsFile_fromFile(ctx, getFullResourcePath(TEST_PUBLICATIONS_FILE), &pubFile); CuAssert(tc, "Unable to read publications file", res == KSI_OK && pubFile != NULL); res = KSI_Integer_new(ctx, 1405382400, &tm); CuAssert(tc, "Unable to create integer", res == KSI_OK && tm != NULL); res = KSI_PublicationsFile_getLatestPublication(pubFile, tm, &pubRec); CuAssert(tc, "Unable to find nearest publication", res == KSI_OK && pubRec != NULL); res = KSI_PublicationRecord_getPublishedData(pubRec, &pubDat); CuAssert(tc, "Unable to get published data", res == KSI_OK && pubDat != NULL); res = KSI_PublicationData_getTime(pubDat, &pubTm); CuAssert(tc, "Unable to get publication time", res == KSI_OK && pubTm != NULL); CuAssert(tc, "Unexpected publication time (this test might fail, if you have recently updated the publications file in the tests)", KSI_Integer_equalsUInt(pubTm, 1405382400)); KSI_PublicationsFile_free(pubFile); KSI_Integer_free(tm); }
int KSI_PublicationsFile_getPublicationDataByTime(const KSI_PublicationsFile *trust, const KSI_Integer *pubTime, KSI_PublicationRecord **pubRec) { int res; size_t i; KSI_PublicationRecord *result = NULL; if (trust == NULL) { res = KSI_INVALID_ARGUMENT; goto cleanup; } KSI_ERR_clearErrors(trust->ctx); if (pubTime == NULL || pubRec == NULL) { KSI_pushError(trust->ctx, res = KSI_INVALID_ARGUMENT, NULL); goto cleanup; } for (i = 0; i < KSI_PublicationRecordList_length(trust->publications); i++) { KSI_PublicationRecord *pr = NULL; KSI_PublicationData *pd = NULL; KSI_Integer *tm = NULL; res = KSI_PublicationRecordList_elementAt(trust->publications, i, &pr); if (res != KSI_OK) { KSI_pushError(trust->ctx, res, NULL); goto cleanup; } res = KSI_PublicationRecord_getPublishedData(pr, &pd); if (res != KSI_OK) { KSI_pushError(trust->ctx, res, NULL); goto cleanup; } res = KSI_PublicationData_getTime(pd, &tm); if (res != KSI_OK) { KSI_pushError(trust->ctx, res, NULL); goto cleanup; } if (KSI_Integer_equals(pubTime, tm)) { result = pr; break; } KSI_nofree(tm); KSI_nofree(pd); } *pubRec = result; res = KSI_OK; cleanup: KSI_nofree(result); return res; }
static int verifyCalendarChainWithPublication(KSI_Signature *sig){ int res = KSI_UNKNOWN_ERROR; KSI_CalendarHashChain *calChain = NULL; KSI_Integer *pubTime = NULL; KSI_DataHash *rootHash = NULL; KSI_PublicationRecord *sigPubRec = NULL; KSI_PublicationData *sigPubData = NULL; KSI_DataHash *publishedHash = NULL; KSI_Integer *publishedTime = NULL; KSI_VerificationStep step = KSI_VERIFY_CALCHAIN_WITH_PUBLICATION; KSI_VerificationResult *info = &sig->verificationResult; if (sig->publication == NULL) { res = KSI_OK; goto cleanup; } KSI_LOG_debug(sig->ctx, "Verifying calendar chain with publication."); calChain = sig->calendarChain; res = KSI_CalendarHashChain_getPublicationTime(calChain, &pubTime); if (res != KSI_OK) goto cleanup; res = KSI_CalendarHashChain_aggregate(calChain, &rootHash); if (res != KSI_OK) goto cleanup; sigPubRec = sig->publication; res = KSI_PublicationRecord_getPublishedData(sigPubRec, &sigPubData); if (res != KSI_OK) goto cleanup; res = KSI_PublicationData_getImprint(sigPubData, &publishedHash); if (res != KSI_OK) goto cleanup; res = KSI_PublicationData_getTime(sigPubData, &publishedTime); if (res != KSI_OK) goto cleanup; if (!KSI_DataHash_equals(rootHash, publishedHash)){ KSI_LOG_logDataHash(sig->ctx, KSI_LOG_DEBUG, "Calendar root hash", rootHash); KSI_LOG_logDataHash(sig->ctx, KSI_LOG_DEBUG, "Published hash", publishedHash); res = KSI_VerificationResult_addFailure(info, step, "Published hash and calendar hash chain root hash mismatch."); goto cleanup; } if (!KSI_Integer_equals(pubTime, publishedTime)){ KSI_LOG_debug(sig->ctx, "Calendar hash chain publication time: %i.", KSI_Integer_getUInt64(pubTime)); KSI_LOG_debug(sig->ctx, "Published publication time: %i.", KSI_Integer_getUInt64(publishedTime)); res = KSI_VerificationResult_addFailure(info, step, "Calendar hash chain publication time mismatch."); goto cleanup; } res = KSI_VerificationResult_addSuccess(info, step, "Calendar chain verified with publication."); cleanup: KSI_DataHash_free(rootHash); return res; }
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 int verifyCalendarChain(KSI_Signature *sig) { int res = KSI_UNKNOWN_ERROR; KSI_DataHash *rootHash = NULL; KSI_Integer *calendarPubTm = NULL; KSI_PublicationData *pubData = NULL; KSI_DataHash *pubHash = NULL; KSI_Integer *pubTime = NULL; KSI_VerificationStep step = KSI_VERIFY_CALCHAIN_WITH_CALAUTHREC; KSI_VerificationResult *info = &sig->verificationResult; if (sig->calendarAuthRec == NULL) { res = KSI_OK; goto cleanup; } KSI_LOG_info(sig->ctx, "Verifying calendar hash chain."); /* Calculate the root hash value. */ res = KSI_CalendarHashChain_aggregate(sig->calendarChain, &rootHash); if (res != KSI_OK) goto cleanup; /* Get the publication time from calendar hash chain. */ res = KSI_CalendarHashChain_getPublicationTime(sig->calendarChain, &calendarPubTm); if (res != KSI_OK) goto cleanup; /* Get publication data. */ res = KSI_CalendarAuthRec_getPublishedData(sig->calendarAuthRec, &pubData); if (res != KSI_OK) goto cleanup; /* Get published hash value. */ res = KSI_PublicationData_getImprint(pubData, &pubHash); if (res != KSI_OK) goto cleanup; /* Get publication time. */ res = KSI_PublicationData_getTime(pubData, &pubTime); if (res != KSI_OK) goto cleanup; if (KSI_Integer_equals(calendarPubTm, pubTime) && KSI_DataHash_equals(rootHash, pubHash)) { res = KSI_VerificationResult_addSuccess(info, step, "Calendar chain and authentication record match."); } else { res = KSI_VerificationResult_addFailure(info, step, "Calendar chain and authentication record mismatch."); } if (res != KSI_OK) goto cleanup; res = KSI_OK; cleanup: KSI_DataHash_free(rootHash); 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]; unsigned len; KSI_ERR_clearErrors(ctx); res = KSI_receivePublicationsFile(ctx, &pubFile); CuAssert(tc, "Unable to get publications file.", res == KSI_OK && pubFile != NULL); 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); }
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]; unsigned len; KSI_ERR_clearErrors(ctx); res = KSI_receivePublicationsFile(ctx, &pubFile); CuAssert(tc, "Unable to get publications file.", res == KSI_OK && pubFile != NULL); 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); }
int KSI_PublicationsFile_getLatestPublication(const KSI_PublicationsFile *trust, const KSI_Integer *pubTime, KSI_PublicationRecord **pubRec) { int res; size_t i; KSI_PublicationRecord *result = NULL; KSI_Integer *result_tm = NULL; if (trust == NULL) { res = KSI_INVALID_ARGUMENT; goto cleanup; } KSI_ERR_clearErrors(trust->ctx); if (pubRec == NULL) { KSI_pushError(trust->ctx, res = KSI_INVALID_ARGUMENT, NULL); goto cleanup; } for (i = 0; i < KSI_PublicationRecordList_length(trust->publications); i++) { KSI_PublicationRecord *pr = NULL; KSI_PublicationData *pd = NULL; KSI_Integer *tm = NULL; res = KSI_PublicationRecordList_elementAt(trust->publications, i, &pr); if (res != KSI_OK) { KSI_pushError(trust->ctx, res, NULL); goto cleanup; } res = KSI_PublicationRecord_getPublishedData(pr, &pd); if (res != KSI_OK) { KSI_pushError(trust->ctx, res, NULL); goto cleanup; } res = KSI_PublicationData_getTime(pd, &tm); if (res != KSI_OK) { KSI_pushError(trust->ctx, res, NULL); goto cleanup; } /* Check if current publication time is after given time. */ if (pubTime == NULL || KSI_Integer_compare(pubTime, tm) <= 0) { /* Check if current publication time is after the latest so far. */ if (result_tm == NULL || KSI_Integer_compare(result_tm, tm) <= 0) { result = pr; result_tm = tm; } } KSI_nofree(tm); KSI_nofree(pd); } *pubRec = result; res = KSI_OK; cleanup: KSI_nofree(result); KSI_nofree(result_tm); return res; }
int KSI_PublicationsFile_getPublicationDataByPublicationString(const KSI_PublicationsFile *pubFile, const char *pubString, KSI_PublicationRecord **pubRec) { int res; KSI_PublicationData *findPubData = NULL; KSI_DataHash *findImprint = NULL; KSI_Integer *findTime = NULL; KSI_PublicationRecord *tmpPubRec = NULL; KSI_PublicationData *tmpPubData = NULL; KSI_DataHash *tmpImprint = NULL; if (pubFile == NULL) { res = KSI_INVALID_ARGUMENT; goto cleanup; } KSI_ERR_clearErrors(pubFile->ctx); if (pubString == NULL || pubRec == NULL) { KSI_pushError(pubFile->ctx, res = KSI_INVALID_ARGUMENT, NULL); goto cleanup; } /* Decode the publication string. */ res = KSI_PublicationData_fromBase32(pubFile->ctx, pubString, &findPubData); if (res != KSI_OK) { KSI_pushError(pubFile->ctx, res, NULL); goto cleanup; } /* Extract the expected imprint. */ res = KSI_PublicationData_getImprint(findPubData, &findImprint); if (res != KSI_OK) { KSI_pushError(pubFile->ctx, res, NULL); goto cleanup; } /* Extract the expected publication time. */ res = KSI_PublicationData_getTime(findPubData, &findTime); if (res != KSI_OK) { KSI_pushError(pubFile->ctx, res, NULL); goto cleanup; } /* Find the publication using the publication time. */ res = KSI_PublicationsFile_getPublicationDataByTime(pubFile, findTime, &tmpPubRec); if (res != KSI_OK) { KSI_pushError(pubFile->ctx, res, NULL); goto cleanup; } if (tmpPubRec != NULL) { /* Extract published data. */ res = KSI_PublicationRecord_getPublishedData(tmpPubRec, &tmpPubData); if (res != KSI_OK) { KSI_pushError(pubFile->ctx, res, NULL); goto cleanup; } /* Extract the time. */ res = KSI_PublicationData_getImprint(tmpPubData, &tmpImprint); if (res != KSI_OK) { KSI_pushError(pubFile->ctx, res, NULL); goto cleanup; } if (!KSI_DataHash_equals(findImprint, tmpImprint)) { KSI_pushError(pubFile->ctx, res = KSI_INVALID_PUBLICATION, NULL); goto cleanup; } } *pubRec = tmpPubRec; res = KSI_OK; cleanup: KSI_PublicationData_free(findPubData); KSI_nofree(findImprint); KSI_nofree(findTime); KSI_nofree(tmpPubRec); KSI_nofree(tmpPubData); KSI_nofree(tmpImprint); 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); }
/** * This function extends the signature to the given publication. * \param[in] sig Initial signature. * \param[in] pubStr Null-terminated c string of the publication. * \param[out] ext Pointer to the receiving pointer to the extended signature. * \return Returns KSI_OK if successful. */ static int extendToPublication(KSI_Signature *sig, const char *pubStr, KSI_Signature **ext) { int res = KSI_UNKNOWN_ERROR; /* Only the published data. */ KSI_PublicationData *pubData = NULL; /* Published data and the references to the actual publications. */ KSI_PublicationRecord *pubRec = NULL; /* Publication time. */ KSI_Integer *pubTime = NULL; /* Signature signing time. */ KSI_Integer *signTime = NULL; /* Parse the publications string. */ res = KSI_PublicationData_fromBase32(ksi, pubStr, &pubData); if (res != KSI_OK) { fprintf(stderr, "Invalid publication: '%s'\n", pubStr); goto cleanup; } /* Verify the publication is newer than the signature. */ res = KSI_Signature_getSigningTime(sig, &signTime); if (res != KSI_OK) goto cleanup; res = KSI_PublicationData_getTime(pubData, &pubTime); if (res != KSI_OK) goto cleanup; if (KSI_Integer_compare(signTime, pubTime) > 0) { fprintf(stderr, "Signature created after publication.\n"); res = KSI_INVALID_ARGUMENT; goto cleanup; } /* Create a publication record. */ res = KSI_PublicationRecord_new(ksi, &pubRec); if (res != KSI_OK) goto cleanup; /* Set the published data value. */ res = KSI_PublicationRecord_setPublishedData(pubRec, pubData); if (res != KSI_OK) goto cleanup; /* The pointer will be free by KSI_PublicatioinRecord_free. */ pubData = NULL; /* NB! If the user wants to store the extended signature, some publication references should * be added to the publication reference. As we are going to discard the signature after * verification, the references are not important. */ /* Extend the signature to the publication. */ res = KSI_Signature_extend(sig, ksi, pubRec, ext); if (res != KSI_OK) { fprintf(stderr, "Unable to to extend the signature to the given publication: '%s'\n", pubStr); goto cleanup; } res = KSI_OK; cleanup: /* We can cleanup the values. */ KSI_PublicationData_free(pubData); KSI_PublicationRecord_free(pubRec); return res; }
static int verifyOnline(KSI_CTX *ctx, KSI_Signature *sig) { int res = KSI_UNKNOWN_ERROR; KSI_ExtendReq *req = NULL; KSI_Integer *start = NULL; KSI_Integer *end = NULL; KSI_RequestHandle *handle = NULL; KSI_DataHash *extHash = NULL; KSI_DataHash *calHash = NULL; KSI_ExtendResp *resp = NULL; KSI_Integer *status = NULL; KSI_CalendarHashChain *calChain = NULL; KSI_DataHash *rootHash = NULL; KSI_DataHash *pubHash = NULL; KSI_VerificationStep step = KSI_VERIFY_CALCHAIN_ONLINE; KSI_VerificationResult *info = &sig->verificationResult; KSI_LOG_info(sig->ctx, "Verifying signature online."); /* Extract start time */ res = KSI_CalendarHashChain_getAggregationTime(sig->calendarChain, &start); if (res != KSI_OK) goto cleanup; /* Clone the start time object */ KSI_Integer_ref(start); if (sig->verificationResult.useUserPublication) { /* Extract end time. */ res = KSI_PublicationData_getTime(sig->verificationResult.userPublication, &end); if (res != KSI_OK) goto cleanup; } res = KSI_createExtendRequest(sig->ctx, start, end, &req); if (res != KSI_OK) goto cleanup; res = KSI_sendExtendRequest(ctx, req, &handle); if (res != KSI_OK) goto cleanup; res = KSI_RequestHandle_perform(handle); if (res != KSI_OK) { KSI_pushError(ctx,res, NULL); goto cleanup; } res = KSI_RequestHandle_getExtendResponse(handle, &resp); if (res != KSI_OK) goto cleanup; /* Verify the correctness of the response. */ res = KSI_ExtendResp_verifyWithRequest(resp, req); if (res != KSI_OK) { KSI_pushError(ctx, res, NULL); goto cleanup; } res = KSI_ExtendResp_getStatus(resp, &status); if (res != KSI_OK) goto cleanup; /* Verify status. */ if (status != NULL && !KSI_Integer_equalsUInt(status, 0)) { KSI_Utf8String *respErr = NULL; char errm[1024]; res = KSI_ExtendResp_getErrorMsg(resp, &respErr); if (res != KSI_OK) goto cleanup; KSI_snprintf(errm, sizeof(errm), "Extend failure from server: '%s'", KSI_Utf8String_cstr(respErr)); res = KSI_VerificationResult_addFailure(info, step, errm); goto cleanup; } res = KSI_ExtendResp_getCalendarHashChain(resp, &calChain); if (res != KSI_OK) goto cleanup; res = KSI_CalendarHashChain_getInputHash(calChain, &extHash); if (res != KSI_OK) goto cleanup; res = KSI_CalendarHashChain_getInputHash(sig->calendarChain, &calHash); if (res != KSI_OK) goto cleanup; if (!KSI_DataHash_equals(extHash, calHash)) { res = KSI_VerificationResult_addFailure(info, step, "Extender returned different input hash for calendar hash chain."); goto cleanup; } if (sig->verificationResult.useUserPublication) { res = KSI_CalendarHashChain_aggregate(calChain, &rootHash); if (res != KSI_OK) goto cleanup; if (!KSI_DataHash_equals(rootHash, pubHash)) { res = KSI_VerificationResult_addFailure(info, step, "External publication imprint mismatch."); goto cleanup; } } res = KSI_VerificationResult_addSuccess(info, step, "Verified online."); cleanup: KSI_Integer_free(start); KSI_ExtendReq_free(req); KSI_RequestHandle_free(handle); KSI_ExtendResp_free(resp); return res; }
static int verifyPublicationWithPubString(KSI_CTX *ctx, KSI_Signature *sig) { int res = KSI_UNKNOWN_ERROR; KSI_VerificationStep step = KSI_VERIFY_PUBLICATION_WITH_PUBSTRING; KSI_VerificationResult *info = &sig->verificationResult; KSI_Integer *time1 = NULL; KSI_Integer *time2 = NULL; KSI_DataHash *hsh1 = NULL; KSI_DataHash *hsh2 = NULL; if (sig->publication == NULL || sig->verificationResult.useUserPublication == false) { res = KSI_OK; goto cleanup; } KSI_LOG_info(ctx, "Verifying publication with publication string"); if (sig->verificationResult.userPublication == NULL) { res = KSI_INVALID_ARGUMENT; goto cleanup; } res = KSI_PublicationData_getTime(sig->verificationResult.userPublication, &time1); if (res != KSI_OK) { res = KSI_INVALID_ARGUMENT; goto cleanup; } res = KSI_PublicationData_getImprint(sig->verificationResult.userPublication, &hsh1); if (res != KSI_OK) { res = KSI_INVALID_ARGUMENT; goto cleanup; } res = KSI_PublicationData_getTime(sig->publication->publishedData, &time2); if (res != KSI_OK) { res = KSI_INVALID_ARGUMENT; goto cleanup; } res = KSI_PublicationData_getImprint(sig->publication->publishedData, &hsh2); if (res != KSI_OK) { res = KSI_INVALID_ARGUMENT; goto cleanup; } if (KSI_Integer_compare(time1, time2) != 0) { KSI_LOG_debug(ctx, "Publication time from publication record:", time2); KSI_LOG_debug(ctx, "Publication time from user publication :", time1); res = KSI_VerificationResult_addFailure(info, step, "Publication not trusted."); goto cleanup; } if (KSI_DataHash_equals(hsh1, hsh2) != 1) { KSI_LOG_logDataHash(ctx, KSI_LOG_DEBUG, "Root hash from publication record:", hsh2); KSI_LOG_logDataHash(ctx, KSI_LOG_DEBUG, "Root hash from user publication:", hsh1); res = KSI_VerificationResult_addFailure(info, step, "Publication not trusted."); goto cleanup; } res = KSI_VerificationResult_addSuccess(info, step, "Publication trusted."); cleanup: return res; }