示例#1
0
文件: base.c 项目: GuardTime/libksi
static int KSI_CTX_setTimeoutSeconds(KSI_CTX *ctx, int timeout, int (*setter)(KSI_NetworkClient*, int)){
	int res = KSI_UNKNOWN_ERROR;
	KSI_NetworkClient *client = NULL;

	KSI_ERR_clearErrors(ctx);
	if (ctx == NULL || ctx->netProvider == NULL) {
		KSI_pushError(ctx, res = KSI_INVALID_ARGUMENT, NULL);
		goto cleanup;
	}

	if (ctx->isCustomNetProvider){
		KSI_pushError(ctx, res = KSI_INVALID_ARGUMENT, "Unable to set timeout after initial network provider replacement.");
		goto cleanup;
	}

	client = ctx->netProvider;

	res = setter(client, timeout);
	if (res != KSI_OK) {
		KSI_pushError(ctx,res, NULL);
		goto cleanup;
	}

	res = KSI_OK;

cleanup:

	return res;
}
示例#2
0
文件: hmac.c 项目: GuardTime/libksi
int KSI_HmacHasher_reset(KSI_HmacHasher *hasher) {
	int res = KSI_UNKNOWN_ERROR;

	if (hasher == NULL) {
		res = KSI_INVALID_ARGUMENT;
		goto cleanup;
	}
	KSI_ERR_clearErrors(hasher->ctx);

	res = KSI_DataHasher_reset(hasher->dataHasher);
	if (res != KSI_OK) {
		KSI_pushError(hasher->ctx, res, NULL);
		goto cleanup;
	}

	/* Hash inner data. */
	KSI_LOG_logBlob(hasher->ctx, KSI_LOG_DEBUG, "Adding ipad", hasher->ipadXORkey, hasher->blockSize);
	res = KSI_DataHasher_add(hasher->dataHasher, hasher->ipadXORkey, hasher->blockSize);
	if (res != KSI_OK) {
		KSI_pushError(hasher->ctx, res, NULL);
		goto cleanup;
	}

	res = KSI_OK;

cleanup:

	return res;
}
示例#3
0
int KSI_Signature_verifyAggregatedHash(KSI_Signature *sig, KSI_CTX *ctx, KSI_DataHash *rootHash, KSI_uint64_t rootLevel) {
	int res = KSI_UNKNOWN_ERROR;
	KSI_CTX *useCtx = ctx;

	KSI_ERR_clearErrors(ctx);

	if (ctx == NULL || sig == NULL || rootHash == NULL) {
		KSI_pushError(ctx, res = KSI_INVALID_ARGUMENT, NULL);
		goto cleanup;
	}

	/* Pick a context to use. */
	if (useCtx == NULL) {
		useCtx = sig->ctx;
	}

	KSI_VerificationResult_reset(&sig->verificationResult);

	/* Set the document hash. */
	sig->verificationResult.documentHash = KSI_DataHash_ref(rootHash);
	sig->verificationResult.docAggrLevel = rootLevel;
	sig->verificationResult.verifyDocumentHash = true;

	res = KSI_Signature_verifyPolicy(sig, KSI_VP_DOCUMENT, useCtx);
	if (res != KSI_OK) {
		KSI_pushError(sig->ctx, res, NULL);
		goto cleanup;
	}

	res = KSI_OK;

cleanup:

	return res;
}
示例#4
0
int KSI_OctetString_toTlv(KSI_CTX *ctx, KSI_OctetString *o, unsigned tag, int isNonCritical, int isForward, KSI_TLV **tlv) {
	int res = KSI_UNKNOWN_ERROR;
	KSI_TLV *tmp = NULL;

	KSI_ERR_clearErrors(ctx);
	if (ctx == NULL || o == NULL || tlv == NULL) {
		KSI_pushError(ctx, res = KSI_INVALID_ARGUMENT, NULL);
		goto cleanup;
	}

	res = KSI_TLV_new(ctx, tag, isNonCritical, isForward, &tmp);
	if (res != KSI_OK) {
		KSI_pushError(ctx, res, NULL);
		goto cleanup;
	}

	res = KSI_TLV_setRawValue(tmp, o->data, o->data_len);
	if (res != KSI_OK) {
		KSI_pushError(ctx, res, NULL);
		goto cleanup;
	}

	*tlv = tmp;
	tmp = NULL;

	res = KSI_OK;

cleanup:

	KSI_TLV_free(tmp);

	return res;
}
示例#5
0
文件: base.c 项目: GuardTime/libksi
int KSI_createSignature(KSI_CTX *ctx, KSI_DataHash *dataHash, KSI_Signature **sig) {
	int res = KSI_UNKNOWN_ERROR;
	KSI_Signature *tmp = NULL;

	KSI_ERR_clearErrors(ctx);
	if (ctx == NULL || dataHash == NULL || sig == NULL) {
		KSI_pushError(ctx, res = KSI_INVALID_ARGUMENT, NULL);
		goto cleanup;
	}

	res = KSI_Signature_sign(ctx, dataHash, &tmp);
	if (res != KSI_OK) {
		KSI_pushError(ctx,res, NULL);
		goto cleanup;
	}

	*sig = tmp;
	tmp = NULL;

	res = KSI_OK;

cleanup:

	KSI_Signature_free(tmp);

	return res;
}
示例#6
0
文件: base.c 项目: GuardTime/libksi
static int KSI_CTX_setUri(KSI_CTX *ctx,
		const char *uri, const char *loginId, const char *key,
		int (*setter)(KSI_NetworkClient*, const char*, const char *, const char *)){
	int res = KSI_UNKNOWN_ERROR;

	KSI_ERR_clearErrors(ctx);
	if (ctx == NULL || uri == NULL) {
		KSI_pushError(ctx, res = KSI_INVALID_ARGUMENT, NULL);
		goto cleanup;
	}

	if (ctx->isCustomNetProvider){
		KSI_pushError(ctx, res = KSI_INVALID_ARGUMENT, "Unable to set url after initial network provider replacement.");
		goto cleanup;
	}

	res = setter(ctx->netProvider, uri, loginId, key);
	if (res != KSI_OK) {
		KSI_pushError(ctx,res, NULL);
		goto cleanup;
	}

	res = KSI_OK;

cleanup:

	return res;
}
示例#7
0
static int checkSignatureInternals(KSI_CTX *ctx, KSI_Signature *sig) {
	int res = KSI_UNKNOWN_ERROR;

	if (ctx == NULL || sig == NULL) {
		res = KSI_INVALID_ARGUMENT;
		goto cleanup;
	}

	/* A valid signature must have at least one aggregation chain. */
	if (sig->aggregationChainList == NULL || KSI_AggregationHashChainList_length(sig->aggregationChainList) == 0) {
		KSI_pushError(ctx, res = KSI_INVALID_FORMAT, "A valid signature must have at least one aggregation hash chain.");
		goto cleanup;
	}

	/* If there is no calendar chain, there can not be a calendar auth record nor a publication record. */
	if (sig->calendarChain == NULL && (sig->calendarAuthRec != NULL || sig->publication != NULL)) {
		KSI_pushError(ctx, KSI_INVALID_FORMAT, "Calendar auth record or publication record may not be specified if the calendar chain is missing.");
		goto cleanup;
	}

	/* Make sure the signature does not have both calendar auth record and a publication in it. */
	if (sig->calendarAuthRec != NULL && sig->publication != NULL) {
		KSI_pushError(ctx, res = KSI_INVALID_FORMAT, "Only calendar auth record or publication record may be present.");
		goto cleanup;
	}

	res = KSI_OK;

cleanup:

	return res;
}
示例#8
0
int KSI_SignatureBuilder_setCalendarHashChain(KSI_SignatureBuilder *builder, KSI_CalendarHashChain *cal) {
	int res = KSI_UNKNOWN_ERROR;
	KSI_CalendarHashChain *tmp = NULL;

	if (builder == NULL || cal == NULL) {
		res = KSI_INVALID_ARGUMENT;
		goto cleanup;
	}

	/* Do not allow overriding of the value, as it is likely an error. */
	if (builder->sig->calendarChain != NULL) {
		KSI_pushError(builder->ctx, res = KSI_INVALID_STATE, "The calendar hash chain has already been set.");
		goto cleanup;
	}

	res =  KSI_Signature_setCalendarChain(builder->sig, tmp = KSI_CalendarHashChain_ref(cal));
	if (res != KSI_OK) {
		KSI_pushError(builder->ctx, res, NULL);
		goto cleanup;
	}
	tmp = NULL;

	res = KSI_OK;

cleanup:

	KSI_CalendarHashChain_free(tmp);

	return res;
}
示例#9
0
文件: base.c 项目: GuardTime/libksi
int KSI_CTX_setDefaultPubFileCertConstraints(KSI_CTX *ctx, const KSI_CertConstraint *arr) {
	int res = KSI_UNKNOWN_ERROR;
	KSI_CertConstraint *tmp = NULL;
	size_t count = 0;
	size_t i;

	KSI_ERR_clearErrors(ctx);
	if (ctx == NULL || arr == NULL) {
		KSI_pushError(ctx, res = KSI_INVALID_ARGUMENT, NULL);
		goto cleanup;
	}

	/* Count the input. */
	while(arr[count++].oid != NULL);

	/* Allocate buffer with extra space for the trailing {NULL, NULL}. */
	tmp = KSI_calloc(count, sizeof(KSI_CertConstraint));
	if (tmp == NULL) {
		KSI_pushError(ctx, res = KSI_OUT_OF_MEMORY, NULL);
		goto cleanup;
	}

	/* Copy the values. */
	for (i = 0; arr[i].oid != NULL; i++) {
		res = KSI_strdup(arr[i].oid, &tmp[i].oid);
		if (res != KSI_OK) {
			KSI_pushError(ctx, res, NULL);
			goto cleanup;
		}

		if (arr[i].val == NULL) {
			KSI_pushError(ctx, res = KSI_INVALID_ARGUMENT, "Expected OID value may not be NULL");
			goto cleanup;
		}

		res = KSI_strdup(arr[i].val, &tmp[i].val);
		if (res != KSI_OK) {
			KSI_pushError(ctx, res, NULL);
			goto cleanup;
		}
	}

	/* Add terminator for the array. */
	tmp[i].oid = NULL;
	tmp[i].val = NULL;

	/* Free the existing constraints. */
	freeCertConstraintsArray(ctx->certConstraints);

	ctx->certConstraints = tmp;
	tmp = NULL;

	res = KSI_OK;

cleanup:

	freeCertConstraintsArray(tmp);

	return res;
}
示例#10
0
文件: hash.c 项目: GuardTime/libksi
int KSI_DataHasher_addOctetString(KSI_DataHasher *hasher, KSI_OctetString *data) {
	int res = KSI_UNKNOWN_ERROR;
	const unsigned char *ptr = NULL;
	size_t len = 0;

	if (hasher == NULL || data == NULL) {
		res = KSI_INVALID_ARGUMENT;
		goto cleanup;
	}

	res = KSI_OctetString_extract(data, &ptr, &len);
	if (res != KSI_OK) {
		KSI_pushError(hasher->ctx, res, NULL);
		goto cleanup;
	}

	res = KSI_DataHasher_add(hasher, ptr, len);
	if (res != KSI_OK) {
		KSI_pushError(hasher->ctx, res, NULL);
		goto cleanup;
	}

	res = KSI_OK;

cleanup:

	return res;
}
示例#11
0
int KSI_PublicationRecord_toBase32(KSI_PublicationRecord *pubRec, char **pubStr) {
	int res;

	if (pubRec == NULL) {
		res = KSI_INVALID_ARGUMENT;
		goto cleanup;
	}

	KSI_ERR_clearErrors(pubRec->ctx);

	if (pubStr == NULL) {
		KSI_pushError(pubRec->ctx, res = KSI_INVALID_ARGUMENT, NULL);
		goto cleanup;
	}


	res = KSI_PublicationData_toBase32(pubRec->publishedData, pubStr);
	if (res != KSI_OK) {
		KSI_pushError(pubRec->ctx, res, NULL);
		goto cleanup;
	}

	res = KSI_OK;

cleanup:

	return res;
}
示例#12
0
int KSI_TlvTemplate_parse(KSI_CTX *ctx, const unsigned char *raw, unsigned raw_len, const KSI_TlvTemplate *tmpl, void *payload) {
	int res = KSI_UNKNOWN_ERROR;
	KSI_TLV *tlv = NULL;
	struct tlv_track_s tr[0xf];

	KSI_ERR_clearErrors(ctx);
	if (ctx == NULL || raw == NULL || tmpl == NULL || payload == NULL) {
		KSI_pushError(ctx, res = KSI_INVALID_ARGUMENT, NULL);
		goto cleanup;
	}

	res = KSI_TLV_parseBlob2(ctx, (unsigned char *)raw, raw_len, 0, &tlv);
	if (res != KSI_OK) {
		KSI_pushError(ctx, res, NULL);
		goto cleanup;
	}

	res = extract(ctx, payload, tlv, tmpl, tr, 0, sizeof(tr));
	if (res != KSI_OK) {
		KSI_pushError(ctx, res, NULL);
		goto cleanup;
	}

	KSI_LOG_logTlv(ctx, KSI_LOG_DEBUG, "Parsed TLV", tlv);

	res = KSI_OK;

cleanup:

	KSI_TLV_free(tlv);

	return res;
}
示例#13
0
int KSI_Utf8StringNZ_toTlv(KSI_CTX *ctx, KSI_Utf8String *o, unsigned tag, int isNonCritical, int isForward, KSI_TLV **tlv) {
	int res = KSI_UNKNOWN_ERROR;
	KSI_TLV *tmp = NULL;

	KSI_ERR_clearErrors(ctx);
	if (ctx == NULL || o == NULL || tlv == NULL) {
		KSI_pushError(ctx, res = KSI_INVALID_ARGUMENT, NULL);
		goto cleanup;
	}

	if (o->len == 0 || (o->len == 1 && o->value[0] == 0)) {
		KSI_pushError(ctx, res = KSI_INVALID_FORMAT, "Empty string value not allowed.");
		goto cleanup;
	}

	res = KSI_Utf8String_toTlv(ctx, o, tag, isNonCritical, isForward, &tmp);
	if (res != KSI_OK) {
		KSI_pushError(ctx, res, NULL);
		goto cleanup;
	}

	*tlv = tmp;
	tmp = NULL;

	res = KSI_OK;

cleanup:

	KSI_TLV_free(tmp);

	return res;
}
示例#14
0
int KSI_Utf8StringNZ_fromTlv(KSI_TLV *tlv, KSI_Utf8String **o) {
	int res = KSI_UNKNOWN_ERROR;
	KSI_CTX *ctx = NULL;
	KSI_Utf8String *tmp = NULL;

	ctx = KSI_TLV_getCtx(tlv);
	KSI_ERR_clearErrors(ctx);
	if (tlv == NULL || o == NULL) {
		KSI_pushError(ctx, res = KSI_INVALID_ARGUMENT, NULL);
		goto cleanup;
	}

	res = KSI_Utf8String_fromTlv(tlv, &tmp);
	if (res != KSI_OK) {
		KSI_pushError(ctx, res, NULL);
		goto cleanup;
	}

	if (tmp->len == 0 || (tmp->len == 1 && tmp->value[0] == 0)) {
		KSI_pushError(ctx, res = KSI_INVALID_FORMAT, "Empty string value not allowed.");
		goto cleanup;
	}

	*o = tmp;
	tmp = NULL;

	res = KSI_OK;

cleanup:

	KSI_nofree(ctx);
	KSI_Utf8String_free(tmp);

	return res;
}
示例#15
0
int KSI_OctetString_LegacyId_getUtf8String(KSI_OctetString *id, KSI_Utf8String **str) {
	int res = KSI_UNKNOWN_ERROR;
	const unsigned char *raw = NULL;
	size_t raw_len;
	KSI_Utf8String *tmp = NULL;

	if (id == NULL || str == NULL) {
		res = KSI_INVALID_ARGUMENT;
		goto cleanup;
	}

	KSI_ERR_clearErrors(id->ctx);

	res = KSI_OctetString_extract(id, &raw, &raw_len);
	if (res != KSI_OK) {
		KSI_pushError(id->ctx, res, NULL);
		goto cleanup;
	}

	res = KSI_Utf8String_new(id->ctx, (char *)(raw + LEGACY_ID_STR_POS), raw[LEGACY_ID_STR_LEN_POS] + 1, &tmp);
	if (res != KSI_OK) {
		KSI_pushError(id->ctx, res, NULL);
		goto cleanup;
	}
	*str = tmp;
	tmp = NULL;

	res = KSI_OK;

cleanup:
	KSI_Utf8String_free(tmp);

	return res;
}
示例#16
0
/*TODO: Not supported*/
int KSI_PKITruststore_addLookupFile(KSI_PKITruststore *trust, const char *path) {
	int res = KSI_UNKNOWN_ERROR;
	HCERTSTORE tmp_FileTrustStore = NULL;
	char buf[1024];

	if (trust == NULL || path == NULL){
		res = KSI_INVALID_ARGUMENT;
		goto cleanup;
	}
	KSI_ERR_clearErrors(trust->ctx);

	/*Open new store */
	tmp_FileTrustStore = CertOpenStore(CERT_STORE_PROV_FILENAME_A, 0, 0, 0, path);
	if (tmp_FileTrustStore == NULL) {
		KSI_LOG_debug(trust->ctx, "%s", getMSError(GetLastError(), buf, sizeof(buf)));
		KSI_pushError(trust->ctx, res = KSI_INVALID_FORMAT, NULL);
		goto cleanup;
	}

	/*Update with priority 0 store*/
	if (!CertAddStoreToCollection(trust->collectionStore, tmp_FileTrustStore, 0, 0)) {
		KSI_LOG_debug(trust->ctx, "%s", getMSError(GetLastError(), buf, sizeof(buf)));
		KSI_pushError(trust->ctx, res = KSI_INVALID_FORMAT, NULL);
		goto cleanup;
	}

	tmp_FileTrustStore = NULL;

	res = KSI_OK;

cleanup:

	if (tmp_FileTrustStore) CertCloseStore(tmp_FileTrustStore, CERT_CLOSE_STORE_CHECK_FLAG);
	return res;
}
示例#17
0
文件: base.c 项目: GuardTime/libksi
int KSI_sendExtendRequest(KSI_CTX *ctx, KSI_ExtendReq *request, KSI_RequestHandle **handle) {
	int res = KSI_UNKNOWN_ERROR;
	KSI_RequestHandle *tmp = NULL;
	KSI_NetworkClient *netProvider = NULL;

	KSI_ERR_clearErrors(ctx);
	if (ctx == NULL || request == NULL || handle == NULL) {
		KSI_pushError(ctx, res = KSI_INVALID_ARGUMENT, NULL);
		goto cleanup;
	}

	netProvider = ctx->netProvider;

	res = KSI_NetworkClient_sendExtendRequest(netProvider, request, &tmp);
	if (res != KSI_OK) {
		KSI_pushError(ctx,res, NULL);
		goto cleanup;
	}

	*handle = tmp;
	tmp = NULL;

	res = KSI_OK;

cleanup:

	KSI_RequestHandle_free(tmp);

	return res;
}
示例#18
0
文件: hash.c 项目: GuardTime/libksi
int KSI_DataHasher_addImprint(KSI_DataHasher *hasher, const KSI_DataHash *hsh) {
	int res = KSI_UNKNOWN_ERROR;
	const unsigned char *imprint;
	size_t imprint_len;

	if (hasher == NULL || hsh == NULL) {
		res = KSI_INVALID_ARGUMENT;
		goto cleanup;
	}

	KSI_ERR_clearErrors(hasher->ctx);

	res = KSI_DataHash_getImprint(hsh, &imprint, &imprint_len);
	if (res != KSI_OK) {
		KSI_pushError(hasher->ctx, res, NULL);
		goto cleanup;
	}

	res = KSI_DataHasher_add(hasher, imprint, imprint_len);
	if (res != KSI_OK) {
		KSI_pushError(hasher->ctx, res, NULL);
		goto cleanup;
	}

	res = KSI_OK;

cleanup:

	return res;
}
示例#19
0
文件: base.c 项目: GuardTime/libksi
int KSI_sendPublicationRequest(KSI_CTX *ctx, const unsigned char *request, size_t request_length, KSI_RequestHandle **handle) {
	int res = KSI_UNKNOWN_ERROR;
	KSI_NetworkClient *netProvider = NULL;

	KSI_ERR_clearErrors(ctx);
	if (ctx == NULL || handle == NULL) {
		KSI_pushError(ctx, res = KSI_INVALID_ARGUMENT, NULL);
		goto cleanup;
	}

	netProvider = ctx->netProvider;

	res = KSI_NetworkClient_sendPublicationsFileRequest(netProvider, handle);
	if (res != KSI_OK) {
		KSI_pushError(ctx,res, NULL);
		goto cleanup;
	}

	res = KSI_OK;

cleanup:

	return res;

}
示例#20
0
文件: hash.c 项目: GuardTime/libksi
int KSI_DataHash_createZero(KSI_CTX *ctx, KSI_HashAlgorithm algo_id, KSI_DataHash **hsh) {
	int res = KSI_UNKNOWN_ERROR;
	KSI_DataHash *tmp = NULL;
	unsigned char buf[KSI_MAX_IMPRINT_LEN];

	if (ctx == NULL || hsh == NULL) {
		res = KSI_INVALID_ARGUMENT;
		goto cleanup;
	}

	memset(buf, 0, sizeof(buf));
	buf[0] = algo_id;

	if (!KSI_isHashAlgorithmSupported(algo_id)) {
		KSI_pushError(ctx, res = KSI_UNAVAILABLE_HASH_ALGORITHM, "Hash algorithm not supported.");
		goto cleanup;
	}

	res = KSI_DataHash_fromImprint(ctx, buf, (KSI_hashAlgorithmInfo[algo_id].outputBitCount >> 3) + 1, &tmp);
	if (res != KSI_OK) {
		KSI_pushError(ctx, res, NULL);
		goto cleanup;
	}

	*hsh = tmp;
	tmp = NULL;

	res = KSI_OK;

cleanup:

	KSI_DataHash_free(tmp);

	return res;
}
示例#21
0
文件: base.c 项目: GuardTime/libksi
int KSI_receivePublicationsFile(KSI_CTX *ctx, KSI_PublicationsFile **pubFile) {
	int res = KSI_UNKNOWN_ERROR;
	KSI_RequestHandle *handle = NULL;
	const unsigned char *raw = NULL;
	size_t raw_len = 0;
	KSI_PublicationsFile *tmp = NULL;

	KSI_ERR_clearErrors(ctx);
	if (ctx == NULL || pubFile == NULL) {
		KSI_pushError(ctx, res = KSI_INVALID_ARGUMENT, NULL);
		goto cleanup;
	}

	/* TODO! Implement mechanism for reloading (e.g cache timeout) */
	if (ctx->publicationsFile == NULL) {
		KSI_LOG_debug(ctx, "Receiving publications file.");

		res = KSI_sendPublicationRequest(ctx, NULL, 0, &handle);
		if (res != KSI_OK) {
			KSI_pushError(ctx,res, NULL);
			goto cleanup;
		}

		res = KSI_RequestHandle_perform(handle);
		if (res != KSI_OK) {
			KSI_pushError(ctx,res, NULL);
			goto cleanup;
		}

		res = KSI_RequestHandle_getResponse(handle, &raw, &raw_len);
		if (res != KSI_OK) {
			KSI_pushError(ctx,res, NULL);
			goto cleanup;
		}

		res = KSI_PublicationsFile_parse(ctx, raw, raw_len, &tmp);
		if (res != KSI_OK) {
			KSI_pushError(ctx,res, NULL);
			goto cleanup;
		}

		ctx->publicationsFile = tmp;
		tmp = NULL;

		KSI_LOG_debug(ctx, "Publications file received.");
	}

	*pubFile = KSI_PublicationsFile_ref(ctx->publicationsFile);

	res = KSI_OK;

cleanup:

	KSI_RequestHandle_free(handle);
	KSI_PublicationsFile_free(tmp);

	return res;

}
示例#22
0
int KSI_SignatureBuilder_close(KSI_SignatureBuilder *builder, KSI_uint64_t rootLevel, KSI_Signature **sig) {
	int res = KSI_UNKNOWN_ERROR;
	KSI_VerificationContext context;
	KSI_PolicyVerificationResult *result = NULL;

	if (builder == NULL || sig == NULL) {
		res = KSI_INVALID_ARGUMENT;
		goto cleanup;
	}

	res = KSI_VerificationContext_init(&context, builder->ctx);
	if (res != KSI_OK) {
		KSI_pushError(builder->ctx, res, NULL);
		goto cleanup;
	}

	/* Make sure the aggregation hash chains are in correct order. */
	res = KSI_AggregationHashChainList_sort(builder->sig->aggregationChainList, aggregationHashChainCmp);
	if (res != KSI_OK) {
		KSI_pushError(builder->ctx, res, NULL);
		goto cleanup;
	}

	res = checkSignatureInternals(builder->ctx, builder->sig);
	if (res != KSI_OK) {
		KSI_pushError(builder->ctx, res, "Signature internal structures are invalid.");
		goto cleanup;
	}

	if (!builder->noVerify) {
		/* Verify the signature. */

		context.signature = builder->sig;
		context.docAggrLevel = rootLevel;

		res = KSI_SignatureVerifier_verify(KSI_VERIFICATION_POLICY_INTERNAL, &context, &result);
		if (res != KSI_OK) {
			KSI_pushError(builder->ctx, res, NULL);
			goto cleanup;
		}

		if (result->finalResult.resultCode != KSI_VER_RES_OK) {
			KSI_pushError(builder->ctx, res = KSI_VERIFICATION_FAILURE, "Internal verification of signature failed.");
			goto cleanup;
		}
	}

	*sig = builder->sig;
	builder->sig = NULL;

	res = KSI_OK;

cleanup:

	KSI_VerificationContext_clean(&context);
	KSI_PolicyVerificationResult_free(result);

	return res;
}
示例#23
0
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;
}
示例#24
0
文件: net_http.c 项目: khushil/libksi
static int prepareRequest(
		KSI_NetworkClient *client,
		void *pdu,
		int (*serialize)(void *, unsigned char **, unsigned *),
		KSI_RequestHandle **handle,
		char *url,
		const char *desc) {
	int res = KSI_UNKNOWN_ERROR;
	KSI_HttpClient *http = (KSI_HttpClient *)client;
	KSI_RequestHandle *tmp = NULL;
	unsigned char *raw = NULL;
	unsigned raw_len = 0;

	if (client == NULL || pdu == NULL || handle == NULL) {
		res = KSI_INVALID_ARGUMENT;
		goto cleanup;
	}
	KSI_ERR_clearErrors(client->ctx);

	res = serialize(pdu, &raw, &raw_len);
	if (res != KSI_OK) {
		KSI_pushError(client->ctx, res, NULL);
		goto cleanup;
	}

	KSI_LOG_logBlob(client->ctx, KSI_LOG_DEBUG, desc, raw, raw_len);

	/* Create a new request handle */
	res = KSI_RequestHandle_new(client->ctx, raw, raw_len, &tmp);
	if (res != KSI_OK) {
		KSI_pushError(client->ctx, res, NULL);
		goto cleanup;
	}

	if (http->sendRequest == NULL) {
		KSI_pushError(client->ctx, res = KSI_UNKNOWN_ERROR, "Send request not initialized.");
		goto cleanup;
	}

	res = http->sendRequest(client, tmp, url);
	if (res != KSI_OK) {
		KSI_pushError(client->ctx, res, NULL);
		goto cleanup;
	}

	*handle = tmp;
	tmp = NULL;

	res = KSI_OK;

cleanup:

	KSI_RequestHandle_free(tmp);
	KSI_free(raw);

	return res;
}
示例#25
0
int KSI_Integer_fromTlv(KSI_TLV *tlv, KSI_Integer **o) {
	int res = KSI_UNKNOWN_ERROR;
	KSI_CTX *ctx = NULL;
	KSI_Integer *tmp = NULL;
	const unsigned char *raw = NULL;
	size_t len;
	size_t i;
	KSI_uint64_t val = 0;

	ctx = KSI_TLV_getCtx(tlv);
	KSI_ERR_clearErrors(ctx);
	if (tlv == NULL || o == NULL) {
		KSI_pushError(ctx, res = KSI_INVALID_ARGUMENT, NULL);
		goto cleanup;
	}

	res = KSI_TLV_getRawValue(tlv, &raw, &len);
	if (res != KSI_OK) {
		KSI_pushError(ctx, res, NULL);
		goto cleanup;
	}

	if (len > 8) {
		KSI_pushError(ctx, res = KSI_INVALID_FORMAT, "Integer larger than 64bit");
		goto cleanup;
	}

	/* Encode the up-to 64bit unsigned integer. */
	for (i = 0; i < len; i++) {
		val = val << 8 | raw[i];
	}

	/* Make sure the integer was coded properly. */
	if (len != KSI_UINT64_MINSIZE(val)) {
		KSI_pushError(ctx, res = KSI_INVALID_FORMAT, "Integer not properly formated.");
		goto cleanup;
	}

	res = KSI_Integer_new(ctx, val, &tmp);
	if (res != KSI_OK) {
		KSI_pushError(ctx, res, NULL);
		goto cleanup;
	}

	*o = tmp;
	tmp = NULL;

	res = KSI_OK;

cleanup:

	KSI_nofree(ctx);
	KSI_Integer_free(tmp);

	return res;
}
示例#26
0
static int KSI_PKITruststore_verifySignatureCertificate(const KSI_PKITruststore *pki, const KSI_PKISignature *signature) {
	int res = KSI_UNKNOWN_ERROR;
	KSI_CTX *ctx = NULL;
	PCCERT_CONTEXT subjectCert = NULL;
	char tmp[256];
	char *magicEmail = NULL;

	if (pki == NULL || signature == NULL){
		res = KSI_INVALID_ARGUMENT;
		goto cleanup;
	}
	ctx = pki->ctx;
	KSI_ERR_clearErrors(ctx);

	res = extractSigningCertificate(signature, &subjectCert);
	if (res != KSI_OK){
		KSI_pushError(ctx, res, NULL);
		goto cleanup;
	}

	//printCertInfo(subjectCert);

	res=KSI_CTX_getPublicationCertEmail(ctx, &magicEmail);
	if (res != KSI_OK){
		KSI_pushError(ctx, res, NULL);
		goto cleanup;
	}

	if (magicEmail != NULL){
		if (CertGetNameString(subjectCert, CERT_NAME_EMAIL_TYPE, 0, NULL, tmp, sizeof(tmp))==1){
			KSI_pushError(ctx, res = KSI_CRYPTO_FAILURE, "Unable to get subjects name from PKI certificate.");
			goto cleanup;
		}

		KSI_LOG_debug(ctx, "CryptoAPI: Subjects E-mail: %s.", tmp);

		if (strcmp(tmp, magicEmail) != 0) {
			KSI_pushError(ctx, res = KSI_PKI_CERTIFICATE_NOT_TRUSTED, "Wrong subject name.");
			goto cleanup;
		}
	}

	res = KSI_PKITruststore_verifyCertificate(pki, subjectCert);
	if (res != KSI_OK){
		KSI_pushError(ctx, res, NULL);
		goto cleanup;
	}

	res = KSI_OK;

cleanup:

	if (subjectCert) CertFreeCertificateContext(subjectCert);

	return res;
}
示例#27
0
int KSI_PKICertificate_new(KSI_CTX *ctx, const void *der, size_t der_len, KSI_PKICertificate **cert) {
	int res = KSI_UNKNOWN_ERROR;
	PCCERT_CONTEXT x509 = NULL;
	KSI_PKICertificate *tmp = NULL;
	char buf[1024];

	KSI_ERR_clearErrors(ctx);
	if (ctx == NULL || der == NULL || der_len == 0 || cert == NULL){
		res = KSI_INVALID_ARGUMENT;
		goto cleanup;
	}

	if (der_len > UINT_MAX) {
		KSI_pushError(ctx, res = KSI_INVALID_ARGUMENT, "Length is more than MAX_INT.");
		goto cleanup;
	}

	x509 = CertCreateCertificateContext(X509_ASN_ENCODING, der, (unsigned)der_len);
	if (x509 == NULL) {
		DWORD error = GetLastError();
		const char *errmsg = getMSError(GetLastError(), buf, sizeof(buf));
		KSI_LOG_debug(ctx, "%s", errmsg);

		if (error == CRYPT_E_ASN1_EOD)
			KSI_pushError(ctx, res = KSI_INVALID_FORMAT, "Invalid PKI certificate. ASN.1 unexpected end of data.");
		else if (error == CRYPT_E_ASN1_MEMORY	)
			KSI_pushError(ctx, res = KSI_OUT_OF_MEMORY, NULL);
		else
			KSI_pushError(ctx, res = KSI_INVALID_FORMAT, errmsg);

		goto cleanup;
	}

	tmp = KSI_new(KSI_PKICertificate);
	if (tmp == NULL) {
		KSI_pushError(ctx, res = KSI_OUT_OF_MEMORY, NULL);
		goto cleanup;
	}

	tmp->ctx = ctx;
	tmp->x509 = x509;
	x509 = NULL;

	*cert = tmp;
	tmp = NULL;

	res = KSI_OK;


cleanup:

	if (x509 != NULL) CertFreeCertificateContext(x509);
	KSI_PKICertificate_free(tmp);

	return res;
}
示例#28
0
static int sendRequest(KSI_NetworkClient *client, KSI_RequestHandle *handle, char *host, unsigned port) {
	int res;
	TcpClientCtx *tc = NULL;

	if (handle == NULL) {
		res = KSI_INVALID_ARGUMENT;
		goto cleanup;
	}

	KSI_ERR_clearErrors(handle->ctx);

	if (client == NULL || host == NULL) {
		KSI_pushError(handle->ctx, res = KSI_INVALID_ARGUMENT, NULL);
		goto cleanup;
	}

	tc = KSI_new(TcpClientCtx);
	if (tc == NULL) {
		KSI_pushError(handle->ctx, res = KSI_OUT_OF_MEMORY, NULL);
		goto cleanup;
	}
	tc->host = NULL;
	tc->port = 0;

	KSI_LOG_debug(handle->ctx, "Tcp: Sending request to: %s:%u", host, port);

	res = KSI_strdup(host, &tc->host);
	if (res != KSI_OK) {
		KSI_pushError(handle->ctx, res, NULL);
		goto cleanup;
	}
	tc->port = port;


	handle->readResponse = readResponse;
	handle->client = client;

	res = KSI_RequestHandle_setImplContext(handle, tc, (void (*)(void *))TcpClientCtx_free);
	if (res != KSI_OK) {
		KSI_pushError(handle->ctx, res, NULL);
		goto cleanup;
	}

	tc = NULL;

	res = KSI_OK;

cleanup:

	TcpClientCtx_free(tc);

	return res;
}
示例#29
0
int KSI_PublicationsFile_getPKICertificateById(const KSI_PublicationsFile *pubFile, const KSI_OctetString *id, KSI_PKICertificate **cert) {
	int res;
	size_t i;
	KSI_CertificateRecord *certRec = NULL;

	if (pubFile == NULL) {
		res = KSI_INVALID_ARGUMENT;
		goto cleanup;
	}

	KSI_ERR_clearErrors(pubFile->ctx);

	if (id == NULL || cert == NULL) {
		KSI_pushError(pubFile->ctx, res = KSI_INVALID_ARGUMENT, NULL);
		goto cleanup;
	}


	for (i = 0; i < KSI_CertificateRecordList_length(pubFile->certificates); i++) {
		KSI_OctetString *cId = NULL;

		res = KSI_CertificateRecordList_elementAt(pubFile->certificates, i, &certRec);
		if (res != KSI_OK) {
			KSI_pushError(pubFile->ctx, res, NULL);
			goto cleanup;
		}

		res = KSI_CertificateRecord_getCertId(certRec, &cId);
		if (res != KSI_OK) {
			KSI_pushError(pubFile->ctx, res, NULL);
			goto cleanup;
		}

		if (KSI_OctetString_equals(cId, id)) {
			res = KSI_CertificateRecord_getCert(certRec, cert);
			if (res != KSI_OK) {
				KSI_pushError(pubFile->ctx, res, NULL);
				goto cleanup;
			}

			break;
		}
	}

	res = KSI_OK;

cleanup:

	KSI_nofree(certRec);

	return res;
}
示例#30
0
文件: hash.c 项目: GuardTime/libksi
int KSI_DataHash_fromDigest(KSI_CTX *ctx, KSI_HashAlgorithm algo_id, const unsigned char *digest, size_t digest_length, KSI_DataHash **hash) {
	int res = KSI_UNKNOWN_ERROR;
	KSI_DataHash *tmp_hash = NULL;

	KSI_ERR_clearErrors(ctx);
	if (ctx == NULL || digest == NULL || digest_length == 0 || hash == NULL) {
		KSI_pushError(ctx, res = KSI_INVALID_ARGUMENT, NULL);
		goto cleanup;
	}

	/* Make sure the algorithm is supported. */
	if (!KSI_isHashAlgorithmSupported(algo_id)) {
		KSI_pushError(ctx, res = KSI_UNAVAILABLE_HASH_ALGORITHM, "Hash algorithm not supported.");
		goto cleanup;
	}

	/* Verify the length of the digest with the algorithm. */
	if (KSI_getHashLength(algo_id) != digest_length) {
		KSI_pushError(ctx, res = KSI_INVALID_FORMAT, "Digest length does not match with algorithm.");
		goto cleanup;
	}

	/* Make sure it fits. */
	if (digest_length > KSI_MAX_IMPRINT_LEN) {
		KSI_pushError(ctx, res = KSI_CRYPTO_FAILURE, "Internal buffer too short to hold imprint");
		goto cleanup;
	}

	tmp_hash = KSI_new(KSI_DataHash);
	if (tmp_hash == NULL) {
		KSI_pushError(ctx, res = KSI_OUT_OF_MEMORY, NULL);
		goto cleanup;
	}

	tmp_hash->ref = 1;
	tmp_hash->ctx = ctx;

	tmp_hash->imprint[0] = (unsigned char)algo_id;
	memcpy(tmp_hash->imprint + 1, digest, digest_length);
	tmp_hash->imprint_length = digest_length + 1;

	*hash = tmp_hash;
	tmp_hash = NULL;

	res = KSI_OK;

cleanup:

	KSI_DataHash_free(tmp_hash);

	return res;
}