diff --git a/Makefile b/Makefile
index 24bef8d4282baa7702d4386193c4291275c708c7..432c3dedf2d6f05e3a46c336c0486a95be63d021 100644
--- a/Makefile
+++ b/Makefile
@@ -792,6 +792,7 @@ LIB_OBJS += replace_object.o
 LIB_OBJS += rerere.o
 LIB_OBJS += resolve-undo.o
 LIB_OBJS += revision.o
+LIB_OBJS += rfc3161.o
 LIB_OBJS += run-command.o
 LIB_OBJS += send-pack.o
 LIB_OBJS += sequencer.o
diff --git a/rfc3161.c b/rfc3161.c
new file mode 100644
index 0000000000000000000000000000000000000000..21a386fe8bd49b164538cdd845238b1c70e4558b
--- /dev/null
+++ b/rfc3161.c
@@ -0,0 +1,219 @@
+#include "cache.h"
+#include "commit.h"
+#include "run-command.h"
+#include "strbuf.h"
+#include "gpg-interface.h"
+#include "rfc3161.h"
+
+static const char *timeutil_cmd = "timestamp-util";
+static const char *ts_signature_begin = "-----BEGIN RFC3161-----";
+static const char *ts_signature_end = "-----END RFC3161-----";
+
+static void sha1_from_strbuf(struct strbuf *buf, unsigned char sha1[20]);
+static void sha1_in_hex(struct strbuf *buf, char sha1_hex[40]);
+
+static int verify_tsr(char *sha1, struct strbuf *base64);
+
+/*
+ * To create a time-stamp signature, get the SHA1 hash of buffer and pass it to
+ * git-timestamp-util. This helper program returns a minimalized TSR which is
+ * appended with some metadata and stored to the git object.
+ */
+int create_time_signature(struct strbuf *buffer, struct strbuf *sig)
+{
+	ssize_t len;
+	char sha1_hex[40];
+	struct strbuf tsr = STRBUF_INIT;
+	struct child_process timeutil = CHILD_PROCESS_INIT;
+	const char *args[] = {
+		timeutil_cmd,
+		"-c",
+		sha1_hex,
+		NULL
+	};
+
+	timeutil.argv = args;
+	timeutil.in = 0;
+	timeutil.out = -1;
+	timeutil.git_cmd = 1;
+
+	sha1_in_hex(buffer, sha1_hex);
+
+	if (start_command(&timeutil))
+		return error(_("could not run git-%s"), timeutil_cmd);
+
+	len = strbuf_read(&tsr, timeutil.out, 1024);
+	close(timeutil.out);
+
+	if (finish_command(&timeutil) || len <= 0)
+		return 1;
+
+	strbuf_addf(sig, "%s\n", ts_signature_begin);
+	strbuf_addf(sig, "Version: 1\n\n");
+	strbuf_addbuf(sig, &tsr);
+	strbuf_addf(sig, "%s\n", ts_signature_end);
+
+	strbuf_release(&tsr);
+	return 0;
+}
+
+/*
+ * To verify a time-stamp signature, extract the time-stamp from a git object,
+ * extract the object id and pass the prepared data to git-timestamp-util, which
+ * will do the verification for us.
+ */
+int verify_time_signature(const char *buf, unsigned long size)
+{
+	char sha1_hex[40];
+	struct strbuf timesig_base64 = STRBUF_INIT;
+	struct strbuf payload = STRBUF_INIT;
+	int ret = 1;
+
+	printf("\n");
+
+	if (!parse_timestamp(buf, size, &timesig_base64, &payload)) {
+		printf("time-stamp: no signature found\n");
+		return 1;
+	}
+
+	/*
+	 * Remove possible inline GPG signature from git object. Note that git
+	 * tags do not use inline signatures for historical reasons, so checking
+	 * the return value of remove_signature would be useless.
+	 * Any tag-like signatures outside of the object header are already
+	 * removed by parse_timestamp.
+	 */
+	remove_signature(&payload);
+	sha1_in_hex(&payload, sha1_hex);
+
+	if (verify_tsr(sha1_hex, &timesig_base64))
+		goto err;
+
+	ret = 0;
+err:
+	strbuf_release(&timesig_base64);
+	strbuf_release(&payload);
+	return ret;
+}
+
+int parse_timestamp(const char *buffer, size_t size, struct strbuf *timestamp,
+		    struct strbuf *payload)
+{
+	int saw_timestamp = -1;
+	const char *line, *tail, *next;
+
+	line = buffer;
+	tail = buffer + size;
+	saw_timestamp = 0;
+
+	/* Search for beginning of time-stamp. */
+	while (line < tail) {
+		next = memchr(line, '\n', tail - line);
+
+		next = next ? next + 1 : tail;
+		if (starts_with(line, time_sig_header) &&
+		    line[time_sig_header_len] == ' ')
+			break;
+
+		strbuf_add(payload, line, next - line);
+		line = next;
+	}
+
+	if (line >= tail)
+		return saw_timestamp;
+
+	/*
+	 * Found beginning of time-stamp.  Do not add -----BEGIN RFC3161-----,
+	 * version information and the separating newline to the buffer.
+	 */
+	line = memchr(line, '\n', tail - line) + 1;
+	line = memchr(line, '\n', tail - line) + 1;
+	line = memchr(line, '\n', tail - line) + 1;
+	saw_timestamp = 1;
+
+	/* Read in time-stamp data. */
+	while (line < tail) {
+		next = memchr(line, '\n', tail - line);
+
+		next = next ? next + 1 : tail;
+		if (line[0] == ' ')
+			line = line + 1;
+		else
+			break;
+
+		/* do not add -----END RFC3161----- to buffer */
+		if (starts_with(line, ts_signature_end)) {
+			line = next;
+			break;
+		}
+
+		strbuf_add(timestamp, line, next - line);
+		line = next;
+	}
+
+	while (line < tail) {
+		next = memchr(line, '\n', tail - line);
+		next = next ? next + 1 : tail;
+
+		if (starts_with(line, PGP_SIGNATURE))
+			break;
+
+		strbuf_add(payload, line, next - line);
+		line = next;
+	}
+
+	return saw_timestamp;
+}
+
+/* Pass the prepared data to git-timestamp-util */
+static int verify_tsr(char *sha1, struct strbuf *base64)
+{
+	struct child_process timeutil = CHILD_PROCESS_INIT;
+	const char *args[] = {
+		timeutil_cmd,
+		"-v",
+		sha1,
+		NULL
+	};
+
+	timeutil.argv = args;
+	timeutil.in = -1;
+	timeutil.out = 0;
+	timeutil.git_cmd = 1;
+
+	if (start_command(&timeutil))
+		return error(_("could not run git-%s"), timeutil_cmd);
+
+	if (write_in_full(timeutil.in, base64->buf, base64->len)
+			  != base64->len) {
+		close(timeutil.in);
+		finish_command(&timeutil);
+		return 1;
+	}
+	close(timeutil.in);
+
+	if (finish_command(&timeutil))
+		return 1;
+
+	return 0;
+}
+
+static void sha1_from_strbuf(struct strbuf *buf, unsigned char sha1[20])
+{
+	git_SHA_CTX c;
+
+	git_SHA1_Init(&c);
+	git_SHA1_Update(&c, buf->buf, buf->len);
+	git_SHA1_Final(sha1, &c);
+}
+
+static void sha1_in_hex(struct strbuf *buf, char sha1_hex[40])
+{
+	char *tmp;
+	unsigned char sha1[20];
+
+	sha1_from_strbuf(buf, sha1);
+	tmp = sha1_to_hex(sha1);
+	strcpy(sha1_hex, tmp);
+}
+
diff --git a/rfc3161.h b/rfc3161.h
new file mode 100644
index 0000000000000000000000000000000000000000..eac91ae1036f264d2edfe25c98bf38d587ac208a
--- /dev/null
+++ b/rfc3161.h
@@ -0,0 +1,12 @@
+#ifndef RFC3161_H
+#define RFC3161_H
+
+#define time_sig_header "timesig"
+#define time_sig_header_len (sizeof(time_sig_header) - 1)
+
+int create_time_signature(struct strbuf *buffer, struct strbuf *sig);
+int verify_time_signature(const char *buf, unsigned long size);
+int parse_timestamp(const char *buffer, size_t size, struct strbuf *timestamp,
+		    struct strbuf *payload);
+
+#endif