static void testMaskingWithMetaDataMultiSig(CuTest *tc) { #define TEST_AGGR_RESPONSE_FILE "resource/tlv/test_meta_data_masking.tlv" static const unsigned char diceRolls[] = {0xd5, 0x58, 0xaf, 0xfa, 0x80, 0x67, 0xf4, 0x2c, 0xd9, 0x48, 0x36, 0x21, 0xd1, 0xab, 0xae, 0x23, 0xed, 0xd6, 0xca, 0x04, 0x72, 0x7e, 0xcf, 0xc7, 0xdb, 0xc7, 0x6b, 0xde, 0x34, 0x77, 0x1e, 0x53}; int res = KSI_UNKNOWN_ERROR; KSI_BlockSigner *bs = NULL; KSI_MultiSignature *ms = NULL; size_t i; KSI_DataHash *hsh = NULL; KSI_Signature *sig = NULL; KSI_DataHash *zero = NULL; KSI_OctetString *iv = NULL; /* Create zero hash. */ res = KSI_DataHash_createZero(ctx, KSI_HASHALG_SHA2_512, &zero); CuAssert(tc, "Unable to create zero hash.", res == KSI_OK && zero != NULL); /* Create random initial vector. */ res = KSI_OctetString_new(ctx, diceRolls, sizeof(diceRolls), &iv); CuAssert(tc, "Unable to create initial vector.", res == KSI_OK && iv != NULL); res = KSI_BlockSigner_new(ctx, KSI_HASHALG_SHA1, zero, iv, &bs); CuAssert(tc, "Unable to create block signer instance with masking.", res == KSI_OK && bs != NULL); addInput(tc, bs, 1); res = KSI_CTX_setAggregator(ctx, getFullResourcePathUri(TEST_AGGR_RESPONSE_FILE), TEST_USER, TEST_PASS); CuAssert(tc, "Unable to set aggregator file URI.", res == KSI_OK); res = KSI_BlockSigner_close(bs, &ms); CuAssert(tc, "Unable to close block signer and extract multi signature.", res == KSI_OK && ms != NULL); res = KSITest_setDefaultPubfileAndVerInfo(ctx); CuAssert(tc, "Unable to set default pubfile, default cert and default pki constraints.", res == KSI_OK); /* Lets loop over all the inputs and try to verify them. */ for (i = 0; input_data[i] != NULL; i++) { res = KSI_DataHash_create(ctx, input_data[i], strlen(input_data[i]), KSI_HASHALG_SHA2_256, &hsh); CuAssert(tc, "Unable to create data hash.", res == KSI_OK && hsh != NULL); res = KSI_MultiSignature_get(ms, hsh, &sig); CuAssert(tc, "Unable to extract signature from the multi signature container.", res == KSI_OK && sig != NULL); res = KSI_Signature_verifyDocument(sig, ctx, (void *)input_data[i], strlen(input_data[i])); CuAssert(tc, "Unable to verify the input data.", res == KSI_OK); KSI_Signature_free(sig); sig = NULL; KSI_DataHash_free(hsh); hsh = NULL; } KSI_OctetString_free(iv); KSI_DataHash_free(zero); KSI_DataHash_free(hsh); KSI_MultiSignature_free(ms); KSI_BlockSigner_free(bs); #undef TEST_AGGR_RESPONSE_FILE }
static void testReset(CuTest *tc) { #define TEST_AGGR_RESPONSE_FILE "resource/tlv/ok-sig-2014-07-01.1-aggr_response.tlv" int res = KSI_UNKNOWN_ERROR; KSI_BlockSigner *bs = NULL; KSI_DataHash *hsh = NULL; KSI_BlockSignerHandle *h = NULL; KSI_Signature *sig = NULL; unsigned char *raw = NULL; size_t len = 0; res = KSI_CTX_setAggregator(ctx, getFullResourcePathUri(TEST_AGGR_RESPONSE_FILE), TEST_USER, TEST_PASS); CuAssert(tc, "Unable to set aggregator file URI.", res == KSI_OK); res = KSITest_DataHash_fromStr(ctx, "0111a700b0c8066c47ecba05ed37bc14dcadb238552d86c659342d1d7e87b8772d", &hsh); CuAssert(tc, "Unable to create data hash.", res == KSI_OK && hsh != NULL); res = KSI_BlockSigner_new(ctx, KSI_HASHALG_SHA1, NULL, NULL, &bs); CuAssert(tc, "Unable to create block signer instance.", res == KSI_OK && bs != NULL); /* Add the temporary leafs. */ res = KSI_BlockSigner_addLeaf(bs, hsh, 0, NULL, NULL); CuAssert(tc, "Unable to add 1st mock hash to the blocksigner.", res == KSI_OK); res = KSI_BlockSigner_addLeaf(bs, hsh, 0, NULL, NULL); CuAssert(tc, "Unable to add 2nd hash to the blocksigner.", res == KSI_OK); res = KSI_BlockSigner_addLeaf(bs, hsh, 0, NULL, NULL); CuAssert(tc, "Unable to add 3rd hash to the blocksigner.", res == KSI_OK); res = KSI_BlockSigner_reset(bs); CuAssert(tc, "Unable to reset the block signer.", res == KSI_OK); res = KSI_BlockSigner_addLeaf(bs, hsh, 0, NULL, &h); CuAssert(tc, "Unable to add actual hash to the blocksigner.", res == KSI_OK && h != NULL); res = KSI_BlockSigner_close(bs, NULL); CuAssert(tc, "Unable to close blocksigner.", res == KSI_OK); res = KSI_BlockSignerHandle_getSignature(h, &sig); CuAssert(tc, "Unable to extract signature from the blocksigner.", res == KSI_OK && sig != NULL); res = KSI_Signature_serialize(sig, &raw, &len); CuAssert(tc, "Unable to serialize signature.", res == KSI_OK && raw != NULL && len > 0); KSI_LOG_logBlob(ctx, KSI_LOG_DEBUG, "Serialized single signature from block signer.", raw, len); KSI_BlockSignerHandle_free(h); KSI_Signature_free(sig); KSI_BlockSigner_free(bs); KSI_DataHash_free(hsh); KSI_free(raw); #undef TEST_AGGR_RESPONSE_FILE }
static void testMultiSig(CuTest *tc) { #define TEST_AGGR_RESPONSE_FILE "resource/tlv/ok-aggr-resp-1460631424.tlv" int res = KSI_UNKNOWN_ERROR; KSI_BlockSigner *bs = NULL; KSI_MultiSignature *ms = NULL; size_t i; KSI_DataHash *hsh = NULL; KSI_Signature *sig = NULL; res = KSI_BlockSigner_new(ctx, KSI_HASHALG_SHA1, NULL, NULL, &bs); CuAssert(tc, "Unable to create block signer instance.", res == KSI_OK && bs != NULL); addInput(tc, bs, 0); res = KSI_CTX_setAggregator(ctx, getFullResourcePathUri(TEST_AGGR_RESPONSE_FILE), TEST_USER, TEST_PASS); CuAssert(tc, "Unable to set aggregator file URI.", res == KSI_OK); res = KSI_BlockSigner_close(bs, &ms); CuAssert(tc, "Unable to close block signer and extract multi signature.", res == KSI_OK && ms != NULL); /* Lets loop over all the inputs and try to verify them. */ for (i = 0; input_data[i] != NULL; i++) { res = KSI_DataHash_create(ctx, input_data[i], strlen(input_data[i]), KSI_HASHALG_SHA2_256, &hsh); CuAssert(tc, "Unable to create data hash.", res == KSI_OK && hsh != NULL); res = KSI_MultiSignature_get(ms, hsh, &sig); CuAssert(tc, "Unable to extract signature from the multi signature container.", res == KSI_OK && sig != NULL); res = KSI_Signature_verifyDocument(sig, ctx, (void *)input_data[i], strlen(input_data[i])); CuAssert(tc, "Unable to verify the input data.", res == KSI_OK); KSI_Signature_free(sig); sig = NULL; KSI_DataHash_free(hsh); hsh = NULL; } KSI_DataHash_free(hsh); KSI_MultiSignature_free(ms); KSI_BlockSigner_free(bs); #undef TEST_AGGR_RESPONSE_FILE }
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; }
static void testMedaData(CuTest *tc) { #define TEST_AGGR_RESPONSE_FILE "resource/tlv/test_meta_data_response.tlv" int res = KSI_UNKNOWN_ERROR; KSI_BlockSigner *bs = NULL; KSI_MetaData *md = NULL; char data[] = "LAPTOP"; char *clientId[] = { "Alice", "Bob", "Claire", NULL }; size_t i; KSI_DataHash *hsh = NULL; KSI_BlockSignerHandle *hndl[] = {NULL, NULL, NULL}; KSI_Signature *sig = NULL; char *id = NULL; res = KSI_DataHash_create(ctx, data, strlen(data), KSI_HASHALG_SHA2_256, &hsh); CuAssert(tc, "Unable to create data hash.", res == KSI_OK && hsh != NULL); res = KSI_BlockSigner_new(ctx, KSI_HASHALG_SHA2_256, NULL, NULL, &bs); CuAssert(tc, "Unable to create block signer instance.", res == KSI_OK && bs != NULL); for (i = 0; clientId[i] != NULL; i++) { res = createMetaData(clientId[i], &md); CuAssert(tc, "Unable to create meta-data.", res == KSI_OK && md != NULL); res = KSI_BlockSigner_addLeaf(bs, hsh, 0, md, &hndl[i]); CuAssert(tc, "Unable to add leaf to the block signer.", res == KSI_OK && hndl[i] != NULL); KSI_MetaData_free(md); md = NULL; } res = KSI_CTX_setAggregator(ctx, getFullResourcePathUri(TEST_AGGR_RESPONSE_FILE), TEST_USER, TEST_PASS); CuAssert(tc, "Unable to set aggregator file URI.", res == KSI_OK); res = KSI_BlockSigner_close(bs, NULL); CuAssert(tc, "Unable to close the blocksigner.", res == KSI_OK); /* Loop over all the handles, and extract the signature. */ for (i = 0; clientId[i] != NULL; i++) { char expId[0xff]; /* Extract the signature. */ res = KSI_BlockSignerHandle_getSignature(hndl[i], &sig); CuAssert(tc, "Unable to extract signature.", res == KSI_OK && sig != NULL); /* Verify the signature. */ res = KSI_verifySignature(ctx, sig); CuAssert(tc, "Unable to verify the extracted signature.", res == KSI_OK); /* Extract the id attribution. */ res = KSI_Signature_getSignerIdentity(sig, &id); CuAssert(tc, "Unable to extract the signer identity.", res == KSI_OK && id != NULL); /* Create the expected id value. */ KSI_snprintf(expId, sizeof(expId), "%s :: %s", "GT :: GT :: release test :: anon http", clientId[i]); CuAssert(tc, "Client id not what expected.", !strcmp(id, expId)); /* Cleanup. */ KSI_Signature_free(sig); sig = NULL; KSI_free(id); id = NULL; KSI_BlockSignerHandle_free(hndl[i]); } KSI_DataHash_free(hsh); KSI_MetaData_free(md); KSI_BlockSigner_free(bs); #undef TEST_AGGR_RESPONSE_FILE }