the keys gpg failed error data and c git gnupg

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

De la fuente git :

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:

  1. El conmutador quita la firma del autor y firma un compromiso.

  2. 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.