keys - gpg public key
¿Qué datos se están firmando cuando git commit--gpg-sign=<key-id> `? (2)
Después de leer el código en commit_tree_extended , parece que los datos utilizados para firmar son la parte desde "árbol" hasta el final del comentario, por supuesto, excluyendo la firma.
En tu ejemplo, debería ser:
tree 70e7c184c3a89c749174b4987830c287fd78952d
author Dan Neumann <[email protected]> 1399683715 -0500
committer Dan Neumann <[email protected]> 1399683715 -0500
Initial commit
Inicio de búfer:
strbuf_init(&buffer, 8192); /* should avoid reallocs for the headers */
strbuf_addf(&buffer, "tree %s/n", sha1_to_hex(tree));
El padre se compromete a atravesar:
/*
* NOTE! This ordering means that the same exact tree merged with a
* different order of parents will be a _different_ changeset even
* if everything else stays the same.
*/
while (parents) {
struct commit_list *next = parents->next;
struct commit *parent = parents->item;
strbuf_addf(&buffer, "parent %s/n",
sha1_to_hex(parent->object.sha1));
free(parents);
parents = next;
}
Información persona / fecha:
if (!author)
author = git_author_info(IDENT_STRICT);
strbuf_addf(&buffer, "author %s/n", author);
strbuf_addf(&buffer, "committer %s/n", git_committer_info(IDENT_STRICT));
if (!encoding_is_utf8)
strbuf_addf(&buffer, "encoding %s/n", git_commit_encoding);
while (extra) {
add_extra_header(&buffer, extra);
extra = extra->next;
}
strbuf_addch(&buffer, ''/n'');
El comentario y la verificación de codificación:
/* And add the comment */
strbuf_addbuf(&buffer, msg);
/* And check the encoding */
if (encoding_is_utf8 && !verify_utf8(&buffer))
fprintf(stderr, commit_utf8_warn);
Ahí es donde ocurre la firma. La firma se agregará después del encabezado.
if (sign_commit && do_sign_commit(&buffer, sign_commit))
return -1;
También habría información para los padres si su compromiso tuviera algo.
Estoy tratando de averiguar cómo firmar / verificar las confirmaciones manualmente, pero no puedo averiguar qué datos se están firmando para crear la firma. En otras palabras, no puedo averiguar qué <data>
en gpg --verify <commit-sig> <data>
debe ser.
Aquí está la parte relevante del código fuente de git: https://github.com/git/git/blob/master/commit.c#L1047-L1231 pero también soy nuevo en C.
Aquí hay algunos datos de ejemplo:
En un nuevo repositorio de git, creo un archivo ledger.txt
y lo ledger.txt
con un compromiso firmado:
git config --global user.signingkey 7E482429
git init
echo "EAC5-531F-38E8-9670-81AE-4E77-C7AA-5FC3-7E48-2429 1/n" > ledger.txt
git add ledger.txt
git commit -m "Initial commit" --gpg-sign=7E482429
Y aquí está en el registro:
git log --show-signature
commit 876793da21833b5b8197b08462523fd6aad3e5ba
gpg: Signature made Fri May 9 20:01:55 2014 CDT using RSA key ID 7E482429
gpg: Good signature from "Dan Neumann <[email protected]>"
Author: Dan Neumann <[email protected]>
Date: Fri May 9 20:01:55 2014 -0500
Initial commit
Aquí está el objeto de confirmación bastante impreso (que vive en .git/objects/87/6793da21833b5b8197b08462523fd6aad3e5ba
):
git cat-file -p 876793da21833b5b8197b08462523fd6aad3e5ba
tree 70e7c184c3a89c749174b4987830c287fd78952d
author Dan Neumann <[email protected]> 1399683715 -0500
committer Dan Neumann <[email protected]> 1399683715 -0500
gpgsig -----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
iQEcBAABAgAGBQJTbXqDAAoJEMeqX8N+SCQpTBIH/3zCpf0w0+xp8hkwz7dTV9Bw
ercZp4UpxKV1HgqCxu2r/nGIuZyabLwTis1rcwXOVC4DgRxO0f2BiP0xnyL3OhJu
CKh8l+HZvvGqVH3Dopm0D/kOxDAWHcjokbyzWBbYJX6WhvT8OI7SSYmwuF4r610h
hkZ1xgjo4p1x9WegY296PzA1wEe6yy9BvvdIpJHoqBVKClgFrZvtE5PidbrAyLGF
Kl/2f0K3peBdo6XP0Zaml8NyQlFmAlCV831hHgUmZsBSRpgh/WNvrDSNILTlFJgY
BOPb2yPP+tiJOXYB66MsjQY9GlX7n43miu5wMtdk1AGqh+26OExbSrZcYVFLk4w=
=sRee
-----END PGP SIGNATURE-----
Initial commit
Y aquí están los contenidos reales del archivo de objeto de confirmación:
hexdump .git/objects/87/6793da21833b5b8197b08462523fd6aad3e5ba | /
zlib-decompress | /
bin-to-ascii
commit 671/0tree 70e7c184c3a89c749174b4987830c287fd78952d/nauthor Dan Neumann <[email protected]> 1399683715 -0500/ncommitter Dan Neumann <[email protected]> 1399683715 -0500/ngpgsig -----BEGIN PGP SIGNATURE-----/n Version: GnuPG v1/n /n iQEcBAABAgAGBQJTbXqDAAoJEMeqX8N+SCQpTBIH/3zCpf0w0+xp8hkwz7dTV9Bw/n ercZp4UpxKV1HgqCxu2r/nGIuZyabLwTis1rcwXOVC4DgRxO0f2BiP0xnyL3OhJu/n CKh8l+HZvvGqVH3Dopm0D/kOxDAWHcjokbyzWBbYJX6WhvT8OI7SSYmwuF4r610h/n hkZ1xgjo4p1x9WegY296PzA1wEe6yy9BvvdIpJHoqBVKClgFrZvtE5PidbrAyLGF/n Kl/2f0K3peBdo6XP0Zaml8NyQlFmAlCV831hHgUmZsBSRpgh/WNvrDSNILTlFJgY/n BOPb2yPP+tiJOXYB66MsjQY9GlX7n43miu5wMtdk1AGqh+26OExbSrZcYVFLk4w=/n =sRee/n -----END PGP SIGNATURE-----/n/nInitial commit/n
Esta respuesta es un trabajo en progreso.
Fondo
Primero, algunas reflexiones sobre los problemas con el actual mecanismo de firma Git.
Idealmente, Git usaría uno de los mecanismos de firma incorporados de GnuPG. Si lo hiciera, sería fácil verificar las confirmaciones de Git sin tener que invocar Git o escribir scripts, simplemente utilizando gpg --verify
o gpg2 --verify
.
En este sentido, es una pena que Git no haya adoptado el mecanismo de firma de "firma separada" de GnuPG, tal como se propuso en la Lista de correo del kernel de Linux en 2005 . Más recientemente, Owen Jacobson ha enumerado algunas razones adicionales por las cuales las firmas separadas serían deseables con respecto al enfoque actual de Git. Señala que actualmente:
Las firmas están incrustadas dentro de los objetos que firman. La firma es parte de la identidad del objeto; dado que Git está direccionado por contenido, esto significa que un objeto no puede ser firmado retroactivamente ni despojado retroactivamente de su firma sin modificar la identidad del objeto. El modelo distribuido de Git significa que este tipo de cambios de identidad son complicados y fáciles de detectar.
Las firmas de compromiso son ciudadanos de segunda clase. Son una adición relativamente reciente a la suite Git, y tanto la implementación como las convenciones sociales a su alrededor continúan evolucionando.
Solo algunos objetos pueden ser firmados. Si bien Git tiene reglas relativamente débiles sobre el flujo de trabajo, el sistema de firmas asume que estás usando uno de los flujos de trabajo más extendidos de Git al limitar tus opciones a una firma como máximo, y al restringir las firmas a etiquetas y confirmaciones (dejando de lado las manchas, los árboles y las referencias). ).
Mike Gerwitz señala una de las ramificaciones más serias del enfoque actual de Git. Las confirmaciones de Git tienen un campo de "autor" y un "autor", lo que permite que el autor y el autor de una confirmación sean dos personas separadas. Sin embargo, los compromisos de Git actualmente permiten la inclusión de una sola firma. Entonces, ¿de quién será la firma? Idealmente, tanto el autor como el autor podrían firmar el compromiso. Las firmas separadas permitirían esto. Así sería anidado firmas en línea, para el caso. Pero debido a que Git no usa ninguna de estas opciones, nos obliga a elegir entre dos opciones insatisfactorias:
El conmutador quita la firma del autor y firma un compromiso.
El conmutador se niega a firmar el commit.
Eso resume las malas noticias. La buena noticia es que el contenedor de Git para GnuPG incluye al menos la opción --show-signature
para el git log
, que verifica las firmas utilizando GnuPG. Esto permite que el registro de Git muestre si se realizó o no una firma con una clave que lleva un UID en el que ha confiado.
Si es así, GnuPG mostrará:
Good signature from "John Doe <[email protected]>"
Si no, GnuPG mostrará:
Good signature from "John Doe <[email protected]>"
WARNING: This key is not certified with a trusted signature!
There is no indication that the signature belongs to the owner.
Tu pregunta
Como se indica en la respuesta de Poko , su compromiso aparece, a primera vista, como equivalente al siguiente documento con firma clara:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
tree 70e7c184c3a89c749174b4987830c287fd78952d
author Dan Neumann <[email protected]> 1399683715 -0500
committer Dan Neumann <[email protected]> 1399683715 -0500
Initial commit
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
iQEcBAABAgAGBQJTbXqDAAoJEMeqX8N+SCQpTBIH/3zCpf0w0+xp8hkwz7dTV9Bw
ercZp4UpxKV1HgqCxu2r/nGIuZyabLwTis1rcwXOVC4DgRxO0f2BiP0xnyL3OhJu
CKh8l+HZvvGqVH3Dopm0D/kOxDAWHcjokbyzWBbYJX6WhvT8OI7SSYmwuF4r610h
hkZ1xgjo4p1x9WegY296PzA1wEe6yy9BvvdIpJHoqBVKClgFrZvtE5PidbrAyLGF
Kl/2f0K3peBdo6XP0Zaml8NyQlFmAlCV831hHgUmZsBSRpgh/WNvrDSNILTlFJgY
BOPb2yPP+tiJOXYB66MsjQY9GlX7n43miu5wMtdk1AGqh+26OExbSrZcYVFLk4w=
=sRee
-----END PGP SIGNATURE-----
Sin embargo, supongamos que guardamos eso como danneau__example.asc
e intentamos verificarlo, aquí está la salida:
$ gpg --verify danneau__example.asc
gpg: Signature made Sat 10 May 2014 02:01:55 BST
gpg: using RSA key C7AA5FC37E482429
gpg: Can''t check signature: public key not found
Lo que GnuPG quiere decir con esto es que debido a que no tengo su clave pública, no puede saber si la firma es buena o mala. Entonces, incluso si manipulo los contenidos, obtengo el mismo resultado:
$ echo "-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
tree 70e7c184c3a89c749174b4987830c287fd78952d
author Dan Neumann <[email protected]> 1399683715 -0500
committer Dan Neumann <[email protected]> 1399683715 -0500
EVIL MESSAGE HERE
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
iQEcBAABAgAGBQJTbXqDAAoJEMeqX8N+SCQpTBIH/3zCpf0w0+xp8hkwz7dTV9Bw
ercZp4UpxKV1HgqCxu2r/nGIuZyabLwTis1rcwXOVC4DgRxO0f2BiP0xnyL3OhJu
CKh8l+HZvvGqVH3Dopm0D/kOxDAWHcjokbyzWBbYJX6WhvT8OI7SSYmwuF4r610h
hkZ1xgjo4p1x9WegY296PzA1wEe6yy9BvvdIpJHoqBVKClgFrZvtE5PidbrAyLGF
Kl/2f0K3peBdo6XP0Zaml8NyQlFmAlCV831hHgUmZsBSRpgh/WNvrDSNILTlFJgY
BOPb2yPP+tiJOXYB66MsjQY9GlX7n43miu5wMtdk1AGqh+26OExbSrZcYVFLk4w=
=sRee
-----END PGP SIGNATURE-----
" | gpg --verify -
gpg: Signature made Sat 10 May 2014 02:01:55 BST
gpg: using RSA key C7AA5FC37E482429
gpg: Can''t check signature: public key not found
Así que esto significa que Poko podría no haber averiguado correctamente qué es exactamente lo que firmaste después de todo.
Para llegar al final de esto, he intentado convertir confirmaciones, firmadas por claves privadas cuyas claves públicas correspondientes poseo, en archivos con firma clara, y pasárselas a GnuPG para verificar. Hasta ahora, solo he recibido respuestas de "mala firma". Si averiguo dónde me voy mal, actualizaré esta respuesta.