int KSI_PublicationRecord_clone(const KSI_PublicationRecord *rec, KSI_PublicationRecord **clone){ int res = KSI_UNKNOWN_ERROR; KSI_PublicationRecord *tmp = NULL; size_t i = 0; if (rec == NULL) { res = KSI_INVALID_ARGUMENT; goto cleanup; } KSI_ERR_clearErrors(rec->ctx); if (clone == NULL) { KSI_pushError(rec->ctx, res = KSI_INVALID_ARGUMENT, NULL); goto cleanup; } res = KSI_PublicationRecord_new(rec->ctx, &tmp); if (res != KSI_OK) { KSI_pushError(rec->ctx, res, NULL); goto cleanup; } /*Copy publication references*/ res = KSI_Utf8StringList_new(&(tmp->publicationRef)); if (res != KSI_OK) goto cleanup; for (i = 0; i < KSI_Utf8StringList_length(rec->publicationRef); i++){ KSI_Utf8String *str = NULL; KSI_Utf8String *ref = NULL; res = KSI_Utf8StringList_elementAt(rec->publicationRef, i, &str); if (res != KSI_OK) { KSI_pushError(rec->ctx, res, NULL); goto cleanup; } res = KSI_Utf8StringList_append(tmp->publicationRef, ref = KSI_Utf8String_ref(str)); if (res != KSI_OK) { /* Cleanup the reference. */ KSI_Utf8String_ref(ref); KSI_pushError(rec->ctx, res, NULL); goto cleanup; } } /*Copy publication data*/ res = KSI_PublicationData_new(rec->ctx, &(tmp->publishedData)); if (res != KSI_OK) { KSI_pushError(rec->ctx, res, NULL); goto cleanup; } tmp->publishedData->ctx = rec->ctx; tmp->publishedData->imprint = KSI_DataHash_ref(rec->publishedData->imprint); tmp->publishedData->time = KSI_Integer_ref(rec->publishedData->time); *clone = tmp; tmp = NULL; res = KSI_OK; cleanup: KSI_PublicationRecord_free(tmp); return res; }
/** * 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; }