Пример #1
0
/* 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, &timestamp);
	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;
}
Пример #2
0
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", &timestamp);

	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);
}
Пример #3
0
int GTHTTP_extendTimestamp(const GTTimestamp *ts_in,
                           const char *url, GTTimestamp **ts_out)
{
    int res = GT_UNKNOWN_ERROR;
    unsigned char *request = NULL;
    size_t request_length;
    unsigned char *response = NULL;
    size_t response_length;
    GTTimestamp *ts_tmp = NULL;

    if (ts_in == NULL || url == NULL || ts_out == NULL) {
        res = GT_INVALID_ARGUMENT;
        goto cleanup;
    }

    res = GTTimestamp_prepareExtensionRequest(ts_in, &request, &request_length);
    if (res != GT_OK) {
        goto cleanup;
    }

    res = GTHTTP_sendRequest(url, request, request_length, &response, &response_length, NULL);
    if (res != GT_OK) {
        goto cleanup;
    }

    res = GTTimestamp_createExtendedTimestamp(ts_in, response, response_length, &ts_tmp);
    if (res != GT_OK) {
        goto cleanup;
    }

    *ts_out = ts_tmp;
    ts_tmp = NULL;

cleanup:

    GTTimestamp_free(ts_tmp);
    GT_free(response);
    GT_free(request);

    return res;
}
Пример #4
0
int GTHTTP_createTimestampHash(const GTDataHash *hash,
                               const char *url, GTTimestamp **timestamp)
{
    int res = GT_UNKNOWN_ERROR;
    unsigned char *request = NULL;
    size_t request_length;
    unsigned char *response = NULL;
    size_t response_length;
    GTTimestamp *ts_tmp = NULL;

    if (hash == NULL || url == NULL || timestamp == NULL) {
        res = GT_INVALID_ARGUMENT;
        goto cleanup;
    }

    res = GTTimestamp_prepareTimestampRequest(hash, &request, &request_length);
    if (res != GT_OK) {
        goto cleanup;
    }

    res = GTHTTP_sendRequest(url, request, request_length, &response, &response_length, NULL);
    if (res != GT_OK) {
        goto cleanup;
    }

    res = GTTimestamp_createTimestamp(response, response_length, &ts_tmp);
    if (res != GT_OK) {
        goto cleanup;
    }

    *timestamp = ts_tmp;
    ts_tmp = NULL;

cleanup:

    GTTimestamp_free(ts_tmp);
    GT_free(response);
    GT_free(request);

    return res;
}
Пример #5
0
int GTHTTP_verifyTimestampHash(const GTTimestamp *ts,
                               const GTDataHash *hash,
                               const char *ext_url, GTTimestamp **ext_ts,
                               const GTPublicationsFile *pub, const char *pub_url,
                               int parse, GTVerificationInfo **ver)
{
    int res = GT_UNKNOWN_ERROR;
    GTPublicationsFile *pub_tmp = NULL;
    GTPubFileVerificationInfo *pub_ver = NULL;
    GTVerificationInfo *ver_tmp = NULL;
    GTTimestamp *ext = NULL;
    int is_ext = 0, is_new = 0;

    if (ts == NULL || hash == NULL || ver == NULL) {
        res = GT_INVALID_ARGUMENT;
        goto cleanup;
    }
    if ((pub != NULL) + (pub_url != NULL) != 1) {
        res = GT_INVALID_ARGUMENT;
        goto cleanup;
    }

    /* Ensure we have a valid publications file. */
    if (pub == NULL) {
        res = GTHTTP_getPublicationsFile(pub_url, &pub_tmp);
        if (res != GT_OK) {
            goto cleanup;
        }
        pub = pub_tmp;
    }
    res = GTPublicationsFile_verify(pub, &pub_ver);
    if (res != GT_OK) {
        goto cleanup;
    }

    /* Check internal consistency of the timestamp. */
    res = GTTimestamp_verify(ts, parse, &ver_tmp);
    if (res != GT_OK) {
        goto cleanup;
    }
    if (ver_tmp == NULL || ver_tmp->implicit_data == NULL) {
        res = GT_UNKNOWN_ERROR;
        goto cleanup;
    }
    if (ver_tmp->verification_errors != GT_NO_FAILURES) {
        goto cleanup;
    }

    /* Check document hash.
     * GT_WRONG_DOCUMENT means the hash did not match.
     * Everything else is some sort of system error. */
    res = GTTimestamp_checkDocumentHash(ts, hash);
    if (res == GT_OK) {
        ver_tmp->verification_status |= GT_DOCUMENT_HASH_CHECKED;
    } else if (res == GT_WRONG_DOCUMENT) {
        ver_tmp->verification_status |= GT_DOCUMENT_HASH_CHECKED;
        ver_tmp->verification_errors |= GT_WRONG_DOCUMENT_FAILURE;
        res = GT_OK;
        goto cleanup;
    } else {
        goto cleanup;
    }

    /* Whether the timestamp is extended. */
    is_ext = ((ver_tmp->verification_status & GT_PUBLIC_KEY_SIGNATURE_PRESENT) == 0);
    /* Whether it is too new to be extended. */
    is_new = (ver_tmp->implicit_data->registered_time > pub_ver->last_publication_time);

    /* If the timestamp is already extended, "promote" it.
     * If it is not extended, but is old enough, attempt to extend it. */
    if (is_ext) {
        ext = (GTTimestamp *) ts;
    } else if (!is_new && ext_url != NULL) {
        res = GTHTTP_extendTimestamp(ts, ext_url, &ext);
        /* If extending fails because of infrastructure failure, fall
         * back to signing key check. Else report errors. */
        if (res == GT_NONSTD_EXTEND_LATER || res == GT_NONSTD_EXTENSION_OVERDUE ||
                (res >= GTHTTP_IMPL_BASE && res <= GTHTTP_HIGHEST)) {
            res = GT_OK;
        }
        if (res != GT_OK) {
            goto cleanup;
        }
    }

    /* If we now have a new timestamp, check internal consistency and document hash. */
    if (ext != NULL && ext != ts) {
        /* Release the old verification info. */
        GTVerificationInfo_free(ver_tmp);
        ver_tmp = NULL;
        /* Re-check consistency. */
        res = GTTimestamp_verify(ext, parse, &ver_tmp);
        if (res != GT_OK) {
            goto cleanup;
        }
        if (ver_tmp == NULL || ver_tmp->implicit_data == NULL) {
            res = GT_UNKNOWN_ERROR;
            goto cleanup;
        }
        if (ver_tmp->verification_errors != GT_NO_FAILURES) {
            goto cleanup;
        }
        /* Re-check document hash. */
        res = GTTimestamp_checkDocumentHash(ts, hash);
        if (res == GT_OK) {
            ver_tmp->verification_status |= GT_DOCUMENT_HASH_CHECKED;
        } else if (res == GT_WRONG_DOCUMENT) {
            ver_tmp->verification_status |= GT_DOCUMENT_HASH_CHECKED;
            ver_tmp->verification_errors |= GT_WRONG_DOCUMENT_FAILURE;
            res = GT_OK;
            goto cleanup;
        } else {
            goto cleanup;
        }
    }

    if (ext != NULL) {
        /* If we now have an extended timestamp, check publication.
         * GT_TRUST_POINT_NOT_FOUND and GT_INVALID_TRUST_POINT mean it did not match.
         * Everything else is some sort of system error. */
        res = GTTimestamp_checkPublication(ext, pub);
        if (res == GT_OK) {
            ver_tmp->verification_status |= GT_PUBLICATION_CHECKED;
        } else if (res == GT_TRUST_POINT_NOT_FOUND || res == GT_INVALID_TRUST_POINT) {
            ver_tmp->verification_status |= GT_PUBLICATION_CHECKED;
            ver_tmp->verification_errors |= GT_NOT_VALID_PUBLICATION;
            res = GT_OK;
        }
    } else {
        /* Otherwise, check signing key.
         * GT_KEY_NOT_PUBLISHED and GT_CERT_TICKET_TOO_OLD mean key not valid.
         * Everything else is some sort of system error. */
        res = GTTimestamp_checkPublicKey(ts, ver_tmp->implicit_data->registered_time, pub);
        if (res == GT_OK) {
            ver_tmp->verification_status |= GT_PUBLICATION_CHECKED;
        } else if (res == GT_KEY_NOT_PUBLISHED || res == GT_CERT_TICKET_TOO_OLD) {
            ver_tmp->verification_status |= GT_PUBLICATION_CHECKED;
            ver_tmp->verification_errors |= GT_NOT_VALID_PUBLIC_KEY_FAILURE;
            res = GT_OK;
        }
    }

cleanup:

    if (res == GT_OK) {
        if (ext_ts != NULL && ext != NULL && ext != ts &&
                ver_tmp->verification_errors == GT_NO_FAILURES) {
            *ext_ts = ext;
            ext = NULL;
        }
        *ver = ver_tmp;
        ver_tmp = NULL;
    }

    if (ext != ts) {
        GTTimestamp_free(ext);
    }
    GTVerificationInfo_free(ver_tmp);
    GTPubFileVerificationInfo_free(pub_ver);
    GTPublicationsFile_free(pub_tmp);

    return res;
}
Пример #6
0
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;
}