/* verify the root hash. This also means we need to compute the * Merkle tree root for the current block. */ int verifyBLOCK_SIG(block_sig_t *bs, gtfile gf, FILE *sigfp, FILE *nsigfp, uint8_t bExtend, gterrctx_t *ectx) { int r; int gtstate; block_sig_t *file_bs = NULL; GTTimestamp *timestamp = NULL; GTVerificationInfo *vrfyInf; GTDataHash *root = NULL; tlvrecord_t rec; if((r = verifySigblkFinish(gf, &root)) != 0) goto done; if((r = rsgt_tlvrdVrfyBlockSig(sigfp, &file_bs, &rec)) != 0) goto done; if(ectx->recNum != bs->recCount) { r = RSGTE_INVLD_RECCNT; goto done; } gtstate = GTTimestamp_DERDecode(file_bs->sig.der.data, file_bs->sig.der.len, ×tamp); if(gtstate != GT_OK) { r = RSGTE_TS_DERDECODE; ectx->gtstate = gtstate; goto done; } gtstate = GTHTTP_verifyTimestampHash(timestamp, root, NULL, NULL, NULL, rsgt_read_puburl, 0, &vrfyInf); if(! (gtstate == GT_OK && vrfyInf->verification_errors == GT_NO_FAILURES) ) { r = RSGTE_INVLD_TIMESTAMP; ectx->gtstate = gtstate; goto done; } if(rsgt_read_showVerified) reportVerifySuccess(ectx, vrfyInf); if(bExtend) if((r = rsgt_extendSig(timestamp, &rec, ectx)) != 0) goto done; if(nsigfp != NULL) if((r = rsgt_tlvwrite(nsigfp, &rec)) != 0) goto done; r = 0; done: if(file_bs != NULL) rsgt_objfree(0x0902, file_bs); if(r != 0) reportError(r, ectx); if(timestamp != NULL) GTTimestamp_free(timestamp); return r; }
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; }