static void reportError(int errcode, gterrctx_t *ectx) { if(ectx->fp != NULL) { fprintf(ectx->fp, "%s[%llu:%llu:%llu]: error[%u]: %s\n", ectx->filename, (long long unsigned) ectx->blkNum, (long long unsigned) ectx->recNum, (long long unsigned) ectx->recNumInFile, errcode, RSGTE2String(errcode)); if(ectx->frstRecInBlk != NULL) fprintf(ectx->fp, "\tBlock Start Record.: '%s'\n", ectx->frstRecInBlk); if(ectx->errRec != NULL) fprintf(ectx->fp, "\tRecord in Question.: '%s'\n", ectx->errRec); if(ectx->computedHash != NULL) { outputHash(ectx->fp, "\tComputed Hash......: ", ectx->computedHash->digest, ectx->computedHash->digest_length, ectx->verbose); } if(ectx->fileHash != NULL) { outputHash(ectx->fp, "\tSignature File Hash: ", ectx->fileHash->data, ectx->fileHash->len, ectx->verbose); } if(errcode == RSGTE_INVLD_TREE_HASH || errcode == RSGTE_INVLD_TREE_HASHID) { fprintf(ectx->fp, "\tTree Level.........: %d\n", (int) ectx->treeLevel); outputHash(ectx->fp, "\tTree Left Hash.....: ", ectx->lefthash->digest, ectx->lefthash->digest_length, ectx->verbose); outputHash(ectx->fp, "\tTree Right Hash....: ", ectx->righthash->digest, ectx->righthash->digest_length, ectx->verbose); } if(errcode == RSGTE_INVLD_TIMESTAMP || errcode == RSGTE_TS_DERDECODE) { fprintf(ectx->fp, "\tPublication Server.: %s\n", rsgt_read_puburl); fprintf(ectx->fp, "\tGT Verify Timestamp: [%u]%s\n", ectx->gtstate, GTHTTP_getErrorString(ectx->gtstate)); } if(errcode == RSGTE_TS_EXTEND || errcode == RSGTE_TS_DERDECODE) { fprintf(ectx->fp, "\tExtending Server...: %s\n", rsgt_extend_puburl); fprintf(ectx->fp, "\tGT Extend Timestamp: [%u]%s\n", ectx->gtstate, GTHTTP_getErrorString(ectx->gtstate)); } if(errcode == RSGTE_TS_DERENCODE) { fprintf(ectx->fp, "\tAPI return state...: [%u]%s\n", ectx->gtstate, GTHTTP_getErrorString(ectx->gtstate)); } } }
/* obviously, this is not an error-reporting function. We still use * ectx, as it has most information we need. */ static void reportVerifySuccess(gterrctx_t *ectx, GTVerificationInfo *vrfyInf) { if(ectx->fp != NULL) { fprintf(ectx->fp, "%s[%llu:%llu:%llu]: block signature successfully verified\n", ectx->filename, (long long unsigned) ectx->blkNum, (long long unsigned) ectx->recNum, (long long unsigned) ectx->recNumInFile); if(ectx->frstRecInBlk != NULL) fprintf(ectx->fp, "\tBlock Start Record.: '%s'\n", ectx->frstRecInBlk); if(ectx->errRec != NULL) fprintf(ectx->fp, "\tBlock End Record...: '%s'\n", ectx->errRec); fprintf(ectx->fp, "\tGT Verify Timestamp: [%u]%s\n", ectx->gtstate, GTHTTP_getErrorString(ectx->gtstate)); GTVerificationInfo_print(ectx->fp, 0, vrfyInf); } }
void timestampIt(GTDataHash *hash) { int r = GT_OK; GTTimestamp *timestamp = NULL; unsigned char *der = NULL; char *sigFile = "logsigner.TIMESTAMP"; size_t der_len; /* Get the timestamp. */ r = GTHTTP_createTimestampHash(hash, "http://stamper.guardtime.net/gt-signingservice", ×tamp); if(r != GT_OK) { fprintf(stderr, "GTHTTP_createTimestampHash() failed: %d (%s)\n", r, GTHTTP_getErrorString(r)); goto done; } /* Encode timestamp. */ r = GTTimestamp_getDEREncoded(timestamp, &der, &der_len); if(r != GT_OK) { fprintf(stderr, "GTTimestamp_getDEREncoded() failed: %d (%s)\n", r, GT_getErrorString(r)); goto done; } /* Save DER-encoded timestamp to file. */ r = GT_saveFile(sigFile, der, der_len); if(r != GT_OK) { fprintf(stderr, "Cannot save timestamp to file %s: %d (%s)\n", sigFile, r, GT_getErrorString(r)); if(r == GT_IO_ERROR) { fprintf(stderr, "\t%d (%s)\n", errno, strerror(errno)); } goto done; } printf("Timestamping succeeded!\n"); done: GT_free(der); GTTimestamp_free(timestamp); }
int main(int argc, char* argv[]) { int res = GT_OK; char *in_file = NULL; char *out_file = NULL; char *tsa_url = NULL; unsigned char *der_in = NULL; size_t der_in_len; unsigned char *der_out = NULL; size_t der_out_len; GTTimestamp *in_timestamp = NULL; GTTimestamp *out_timestamp = NULL; /* Read arguments. */ if (argc != 4) { printf("Usage: %s timestamp_in_file timestamp_out_file verifier_url\n", argv[0]); goto cleanup; } in_file = argv[1]; out_file = argv[2]; tsa_url = argv[3]; /* Init GuardTime libraries. */ res = GT_init(); if (res != GT_OK) { fprintf(stderr, "GT_init() failed: %d (%s)\n", res, GT_getErrorString(res)); goto cleanup; } res = GTHTTP_init("C SDK example", 1); if (res != GT_OK) { fprintf(stderr, "GTHTTP_init() failed: %d (%s)\n", res, GTHTTP_getErrorString(res)); goto cleanup; } /* Read timestamp file. */ res = GT_loadFile(in_file, &der_in, &der_in_len); if (res != GT_OK) { fprintf(stderr, "Cannot load timestamp file %s: %d (%s)\n", in_file, res, GT_getErrorString(res)); if (res == GT_IO_ERROR) { fprintf(stderr, "\t%d (%s)\n", errno, strerror(errno)); } goto cleanup; } /* Decode timestamp. */ res = GTTimestamp_DERDecode(der_in, der_in_len, &in_timestamp); if (res != GT_OK) { fprintf(stderr, "GTTimestamp_DERDecode() failed: %d (%s)\n", res, GT_getErrorString(res)); goto cleanup; } /* Extend timestamp. */ res = GTHTTP_extendTimestamp(in_timestamp, tsa_url, &out_timestamp); if (res != GT_OK) { fprintf(stderr, "GTHTTP_extendTimestamp() failed: %d (%s)\n", res, GTHTTP_getErrorString(res)); goto cleanup; } /* Encode timestamp. */ res = GTTimestamp_getDEREncoded(out_timestamp, &der_out, &der_out_len); if (res != GT_OK) { fprintf(stderr, "GTTimestamp_getDEREncoded() returned %d (%s)\n", res, GT_getErrorString(res)); goto cleanup; } /* Save DER-encoded timestamp to file. */ res = GT_saveFile(out_file, der_out, der_out_len); if (res != GT_OK) { fprintf(stderr, "Cannot save extended timestamp to file %s: %d (%s)\n", out_file, res, GT_getErrorString(res)); if (res == GT_IO_ERROR) { fprintf(stderr, "\t%d (%s)\n", errno, strerror(errno)); } goto cleanup; } printf("Extending succeeded!\n"); cleanup: GT_free(der_out); GTTimestamp_free(out_timestamp); GTTimestamp_free(in_timestamp); GT_free(der_in); /* Finalize GuardTime libraries. */ GTHTTP_finalize(); GT_finalize(); return res == GT_OK ? EXIT_SUCCESS : EXIT_FAILURE; }