{"thread":{"id":"48897","subject":"[PATCH v4 2/7] t/t7510: check the validation of the new config gpg.format","startedAt":"2018-07-17T12:50:33Z","lastAt":"2018-07-20T15:42:05Z","messageCount":24,"participants":["Henning Schild","Junio C Hamano","Taylor Blau"],"isPatch":true,"patchVersion":4,"patchTotal":7},"messages":[{"id":"352776","messageId":"2f806c4fa4454af59344f0f0e77d1ae8048aa841.1531831244.git.henning.schild@siemens.com","threadId":"48897","inReplyTo":"cover.1531831244.git.henning.schild@siemens.com","subject":"[PATCH v4 2/7] t/t7510: check the validation of the new config gpg.format","fromName":"Henning Schild","fromEmail":"henning.schild@siemens.com","sentAt":"2018-07-17T12:50:08Z","receivedAt":"2018-07-17T12:50:33Z","isPatch":true,"sender":{"key":"henning.schild@siemens.com","avatar":"https://avatars.githubusercontent.com/u/7237877?v=4"},"body":"Test setting gpg.format to both invalid and valid values.\n\nSigned-off-by: Henning Schild <henning.schild@siemens.com>\n---\n t/t7510-signed-commit.sh | 9 +++++++++\n 1 file changed, 9 insertions(+)\n\ndiff --git a/t/t7510-signed-commit.sh b/t/t7510-signed-commit.sh\nindex 6e2015ed9..7bdad570c 100755\n--- a/t/t7510-signed-commit.sh\n+++ b/t/t7510-signed-commit.sh\n@@ -227,4 +227,13 @@ test_expect_success GPG 'log.showsignature behaves like --show-signature' '\n \tgrep \"gpg: Good signature\" actual\n '\n \n+test_expect_success GPG 'check config gpg.format values' '\n+\ttest_config gpg.format openpgp &&\n+\tgit commit -S --amend -m \"success\" &&\n+\ttest_config gpg.format OpEnPgP &&\n+\ttest_must_fail git commit -S --amend -m \"fail\" &&\n+\ttest_config gpg.format malformed &&\n+\ttest_must_fail git commit -S --amend -m \"fail\"\n+'\n+\n test_done\n-- \n2.16.4\n\n"},{"id":"352777","messageId":"8330bd5b90aec511e20d21cd0c466752e4ada4b1.1531831244.git.henning.schild@siemens.com","threadId":"48897","inReplyTo":"cover.1531831244.git.henning.schild@siemens.com","subject":"[PATCH v4 4/7] gpg-interface: do not hardcode the key string len anymore","fromName":"Henning Schild","fromEmail":"henning.schild@siemens.com","sentAt":"2018-07-17T12:50:10Z","receivedAt":"2018-07-17T12:50:35Z","isPatch":true,"sender":{"key":"henning.schild@siemens.com","avatar":"https://avatars.githubusercontent.com/u/7237877?v=4"},"body":"gnupg does print the keyid followed by a space and the signer comes\nnext. The same pattern is also used in gpgsm, but there the key length\nwould be 40 instead of 16. Instead of hardcoding the expected length,\nfind the first space and calculate it.\nInput that does not match the expected format will be ignored now,\nbefore we jumped to found+17 which might have been behind the end of an\nunexpected string.\n\nSigned-off-by: Henning Schild <henning.schild@siemens.com>\n---\n gpg-interface.c | 7 ++++---\n 1 file changed, 4 insertions(+), 3 deletions(-)\n\ndiff --git a/gpg-interface.c b/gpg-interface.c\nindex a02db7658..51cad9081 100644\n--- a/gpg-interface.c\n+++ b/gpg-interface.c\n@@ -95,10 +95,11 @@ static void parse_gpg_output(struct signature_check *sigc)\n \t\tsigc->result = sigcheck_gpg_status[i].result;\n \t\t/* The trust messages are not followed by key/signer information */\n \t\tif (sigc->result != 'U') {\n-\t\t\tsigc->key = xmemdupz(found, 16);\n+\t\t\tnext = strchrnul(found, ' ');\n+\t\t\tsigc->key = xmemdupz(found, next - found);\n \t\t\t/* The ERRSIG message is not followed by signer information */\n-\t\t\tif (sigc-> result != 'E') {\n-\t\t\t\tfound += 17;\n+\t\t\tif (*next && sigc-> result != 'E') {\n+\t\t\t\tfound = next + 1;\n \t\t\t\tnext = strchrnul(found, '\\n');\n \t\t\t\tsigc->signer = xmemdupz(found, next - found);\n \t\t\t}\n-- \n2.16.4\n\n"},{"id":"352778","messageId":"afe7d2ef577d265ace458ef73f7a18b9ded91cd8.1531831244.git.henning.schild@siemens.com","threadId":"48897","inReplyTo":"cover.1531831244.git.henning.schild@siemens.com","subject":"[PATCH v4 3/7] gpg-interface: introduce an abstraction for multiple gpg formats","fromName":"Henning Schild","fromEmail":"henning.schild@siemens.com","sentAt":"2018-07-17T12:50:09Z","receivedAt":"2018-07-17T12:50:35Z","isPatch":true,"sender":{"key":"henning.schild@siemens.com","avatar":"https://avatars.githubusercontent.com/u/7237877?v=4"},"body":"Create a struct that holds the format details for the supported formats.\nAt the moment that is still just \"openpgp\". This commit prepares for the\nintroduction of more formats, that might use other programs and match\nother signatures.\n\nSigned-off-by: Henning Schild <henning.schild@siemens.com>\n---\n gpg-interface.c | 88 +++++++++++++++++++++++++++++++++++++++++++--------------\n 1 file changed, 67 insertions(+), 21 deletions(-)\n\ndiff --git a/gpg-interface.c b/gpg-interface.c\nindex b39a27980..a02db7658 100644\n--- a/gpg-interface.c\n+++ b/gpg-interface.c\n@@ -7,11 +7,52 @@\n #include \"tempfile.h\"\n \n static char *configured_signing_key;\n-static const char *gpg_format = \"openpgp\";\n-static const char *gpg_program = \"gpg\";\n+struct gpg_format {\n+\tconst char *name;\n+\tconst char *program;\n+\tconst char **verify_args;\n+\tconst char **sigs;\n+};\n+\n+static const char *openpgp_verify_args[] = {\n+\t\"--keyid-format=long\",\n+\tNULL\n+};\n+static const char *openpgp_sigs[] = {\n+\t\"-----BEGIN PGP SIGNATURE-----\",\n+\t\"-----BEGIN PGP MESSAGE-----\",\n+\tNULL\n+};\n+\n+static struct gpg_format gpg_format[] = {\n+\t{ .name = \"openpgp\", .program = \"gpg\",\n+\t  .verify_args = openpgp_verify_args,\n+\t  .sigs = openpgp_sigs\n+\t},\n+};\n+\n+static struct gpg_format *use_format = &gpg_format[0];\n \n-#define PGP_SIGNATURE \"-----BEGIN PGP SIGNATURE-----\"\n-#define PGP_MESSAGE \"-----BEGIN PGP MESSAGE-----\"\n+static struct gpg_format *get_format_by_name(const char *str)\n+{\n+\tint i;\n+\n+\tfor (i = 0; i < ARRAY_SIZE(gpg_format); i++)\n+\t\tif (!strcmp(gpg_format[i].name, str))\n+\t\t\treturn gpg_format + i;\n+\treturn NULL;\n+}\n+\n+static struct gpg_format *get_format_by_sig(const char *sig)\n+{\n+\tint i, j;\n+\n+\tfor (i = 0; i < ARRAY_SIZE(gpg_format); i++)\n+\t\tfor (j = 0; gpg_format[i].sigs[j]; j++)\n+\t\t\tif (starts_with(sig, gpg_format[i].sigs[j]))\n+\t\t\t\treturn gpg_format + i;\n+\treturn NULL;\n+}\n \n void signature_check_clear(struct signature_check *sigc)\n {\n@@ -102,12 +143,6 @@ void print_signature_buffer(const struct signature_check *sigc, unsigned flags)\n \t\tfputs(output, stderr);\n }\n \n-static int is_gpg_start(const char *line)\n-{\n-\treturn starts_with(line, PGP_SIGNATURE) ||\n-\t\tstarts_with(line, PGP_MESSAGE);\n-}\n-\n size_t parse_signature(const char *buf, size_t size)\n {\n \tsize_t len = 0;\n@@ -115,7 +150,7 @@ size_t parse_signature(const char *buf, size_t size)\n \twhile (len < size) {\n \t\tconst char *eol;\n \n-\t\tif (is_gpg_start(buf + len))\n+\t\tif (get_format_by_sig(buf + len))\n \t\t\tmatch = len;\n \n \t\teol = memchr(buf + len, '\\n', size - len);\n@@ -132,6 +167,9 @@ void set_signing_key(const char *key)\n \n int git_gpg_config(const char *var, const char *value, void *cb)\n {\n+\tstruct gpg_format *fmt = NULL;\n+\tchar *fmtname = NULL;\n+\n \tif (!strcmp(var, \"user.signingkey\")) {\n \t\tif (!value)\n \t\t\treturn config_error_nonbool(var);\n@@ -142,17 +180,20 @@ int git_gpg_config(const char *var, const char *value, void *cb)\n \tif (!strcmp(var, \"gpg.format\")) {\n \t\tif (!value)\n \t\t\treturn config_error_nonbool(var);\n-\t\tif (strcmp(value, \"openpgp\"))\n+\t\tfmt = get_format_by_name(value);\n+\t\tif (!fmt)\n \t\t\treturn error(\"unsupported value for %s: %s\",\n \t\t\t\t     var, value);\n-\t\treturn git_config_string(&gpg_format, var, value);\n+\t\tuse_format = fmt;\n+\t\treturn 0;\n \t}\n \n-\tif (!strcmp(var, \"gpg.program\")) {\n-\t\tif (!value)\n-\t\t\treturn config_error_nonbool(var);\n-\t\tgpg_program = xstrdup(value);\n-\t\treturn 0;\n+\tif (!strcmp(var, \"gpg.program\"))\n+\t\tfmtname = \"openpgp\";\n+\n+\tif (fmtname) {\n+\t\tfmt = get_format_by_name(fmtname);\n+\t\treturn git_config_string(&fmt->program, var, value);\n \t}\n \n \treturn 0;\n@@ -173,7 +214,7 @@ int sign_buffer(struct strbuf *buffer, struct strbuf *signature, const char *sig\n \tstruct strbuf gpg_status = STRBUF_INIT;\n \n \targv_array_pushl(&gpg.args,\n-\t\t\t gpg_program,\n+\t\t\t use_format->program,\n \t\t\t \"--status-fd=2\",\n \t\t\t \"-bsau\", signing_key,\n \t\t\t NULL);\n@@ -211,6 +252,7 @@ int verify_signed_buffer(const char *payload, size_t payload_size,\n \t\t\t struct strbuf *gpg_output, struct strbuf *gpg_status)\n {\n \tstruct child_process gpg = CHILD_PROCESS_INIT;\n+\tstruct gpg_format *fmt;\n \tstruct tempfile *temp;\n \tint ret;\n \tstruct strbuf buf = STRBUF_INIT;\n@@ -226,10 +268,14 @@ int verify_signed_buffer(const char *payload, size_t payload_size,\n \t\treturn -1;\n \t}\n \n+\tfmt = get_format_by_sig(signature);\n+\tif (!fmt)\n+\t\tBUG(\"bad signature '%s'\", signature);\n+\n+\targv_array_push(&gpg.args, fmt->program);\n+\targv_array_pushv(&gpg.args, fmt->verify_args);\n \targv_array_pushl(&gpg.args,\n-\t\t\t gpg_program,\n \t\t\t \"--status-fd=1\",\n-\t\t\t \"--keyid-format=long\",\n \t\t\t \"--verify\", temp->filename.buf, \"-\",\n \t\t\t NULL);\n \n-- \n2.16.4\n\n"},{"id":"352779","messageId":"7115813b993ca123a4e5774878d042ec0941d0b8.1531831244.git.henning.schild@siemens.com","threadId":"48897","inReplyTo":"cover.1531831244.git.henning.schild@siemens.com","subject":"[PATCH v4 5/7] gpg-interface: introduce new config to select per gpg format program","fromName":"Henning Schild","fromEmail":"henning.schild@siemens.com","sentAt":"2018-07-17T12:50:11Z","receivedAt":"2018-07-17T12:50:36Z","isPatch":true,"sender":{"key":"henning.schild@siemens.com","avatar":"https://avatars.githubusercontent.com/u/7237877?v=4"},"body":"Supporting multiple signing formats we will have the need to configure a\ncustom program each. Add a new config value to cater for that.\n\nSigned-off-by: Henning Schild <henning.schild@siemens.com>\n---\n Documentation/config.txt | 5 +++++\n gpg-interface.c          | 2 +-\n 2 files changed, 6 insertions(+), 1 deletion(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex ac373e3f4..0e871346a 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -1832,6 +1832,11 @@ gpg.format::\n \tSpecifies which key format to use when signing with `--gpg-sign`.\n \tDefault is \"openpgp\", that is also the only supported value.\n \n+gpg.<format>.program::\n+\tUse this to customize the program used for the signing format you\n+\tchose. (see `gpg.program` and `gpg.format`) `gpg.program` can still\n+\tbe used as a legacy synonym for\t`gpg.openpgp.program`.\n+\n gui.commitMsgWidth::\n \tDefines how wide the commit message window is in the\n \tlinkgit:git-gui[1]. \"75\" is the default.\ndiff --git a/gpg-interface.c b/gpg-interface.c\nindex 51cad9081..a158f08c1 100644\n--- a/gpg-interface.c\n+++ b/gpg-interface.c\n@@ -189,7 +189,7 @@ int git_gpg_config(const char *var, const char *value, void *cb)\n \t\treturn 0;\n \t}\n \n-\tif (!strcmp(var, \"gpg.program\"))\n+\tif (!strcmp(var, \"gpg.program\") || !strcmp(var, \"gpg.openpgp.program\"))\n \t\tfmtname = \"openpgp\";\n \n \tif (fmtname) {\n-- \n2.16.4\n\n"},{"id":"352780","messageId":"cover.1531831244.git.henning.schild@siemens.com","threadId":"48897","inReplyTo":null,"subject":"[PATCH v4 0/7] X509 (gpgsm) commit signing support","fromName":"Henning Schild","fromEmail":"henning.schild@siemens.com","sentAt":"2018-07-17T12:50:06Z","receivedAt":"2018-07-17T12:50:36Z","isPatch":true,"sender":{"key":"henning.schild@siemens.com","avatar":"https://avatars.githubusercontent.com/u/7237877?v=4"},"body":"Changes in v4:\n - make gpg.format matching case sensitive\n - (final?) coding style and wording changes\n\nChanges in v3:\n - drop patches 1 and 2 known from < v3, see pu hs/push-cert-check-cleanup\n - dropped some testcases from p6, added two t7004 bad key/sig\n - ship a binary x509 certificate for tests, no generation anymore\n - silence gpgsm in tests\n - switch all tests to use test_config instead of \"git config\"\n - p4 deal with invalid input\n - p3 several refactorings, see \"PATCH v2 5/9\" discussion\n\nChanges in v2:\n - removed trailing commas in array initializers and add leading space\n - replaced assert(0) with BUG in p5\n - consolidated 2 format lookups reusing get_format_data p5\n - changed from format \"PGP\" to \"openpgp\", later X509 to \"x509\"\n - use strcasecmp instead of strcmp for format matching\n - introduce gpg.<format>.program in p8, no gpg.programX509 anymore\n - moved t/7510 patch inbetween the two patches changing validation code\n - changed t/7510 patch to use test_config and test_must_fail\n\nThis series adds support for signing commits with gpgsm.\n\nThe first 5 patches prepare for the introduction of the actual feature in\npatch 6.\nFinally patch 7 extends the testsuite to cover the new feature.\n\nThis series can be seen as a follow up of a series that appeared under\nthe name \"gpg-interface: Multiple signing tools\" in april 2018 [1]. After\nthat series was not merged i decided to get my patches ready. The\noriginal series aimed at being generic for any sort of signing tool, while\nthis series just introduced the X509 variant of gpg. (gpgsm)\nI collected authors and reviewers of that first series and already put them\non cc.\n\n[1] https://public-inbox.org/git/20180409204129.43537-1-mastahyeti@gmail.com/\n\nHenning Schild (7):\n  gpg-interface: add new config to select how to sign a commit\n  t/t7510: check the validation of the new config gpg.format\n  gpg-interface: introduce an abstraction for multiple gpg formats\n  gpg-interface: do not hardcode the key string len anymore\n  gpg-interface: introduce new config to select per gpg format program\n  gpg-interface: introduce new signature format \"x509\" using gpgsm\n  gpg-interface t: extend the existing GPG tests with GPGSM\n\n Documentation/config.txt   |  10 +++++\n gpg-interface.c            | 108 +++++++++++++++++++++++++++++++++++++--------\n t/lib-gpg.sh               |  28 +++++++++++-\n t/lib-gpg/gpgsm-gen-key.in |   8 ++++\n t/lib-gpg/gpgsm_cert.p12   | Bin 0 -> 2652 bytes\n t/t4202-log.sh             |  39 ++++++++++++++++\n t/t5534-push-signed.sh     |  52 ++++++++++++++++++++++\n t/t7004-tag.sh             |  13 ++++++\n t/t7030-verify-tag.sh      |  33 ++++++++++++++\n t/t7510-signed-commit.sh   |   9 ++++\n 10 files changed, 281 insertions(+), 19 deletions(-)\n create mode 100644 t/lib-gpg/gpgsm-gen-key.in\n create mode 100644 t/lib-gpg/gpgsm_cert.p12\n\n-- \n2.16.4\n\n"},{"id":"352781","messageId":"bc760e786ae09ef5b14caccd5b8e2ca8f0982950.1531831244.git.henning.schild@siemens.com","threadId":"48897","inReplyTo":"cover.1531831244.git.henning.schild@siemens.com","subject":"[PATCH v4 1/7] gpg-interface: add new config to select how to sign a commit","fromName":"Henning Schild","fromEmail":"henning.schild@siemens.com","sentAt":"2018-07-17T12:50:07Z","receivedAt":"2018-07-17T12:50:42Z","isPatch":true,"sender":{"key":"henning.schild@siemens.com","avatar":"https://avatars.githubusercontent.com/u/7237877?v=4"},"body":"Add \"gpg.format\" where the user can specify which type of signature to\nuse for commits. At the moment only \"openpgp\" is supported and the value is\nnot even used. This commit prepares for a new types of signatures.\n\nSigned-off-by: Henning Schild <henning.schild@siemens.com>\n---\n Documentation/config.txt |  4 ++++\n gpg-interface.c          | 10 ++++++++++\n 2 files changed, 14 insertions(+)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 1cc18a828..ac373e3f4 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -1828,6 +1828,10 @@ gpg.program::\n \tsigned, and the program is expected to send the result to its\n \tstandard output.\n \n+gpg.format::\n+\tSpecifies which key format to use when signing with `--gpg-sign`.\n+\tDefault is \"openpgp\", that is also the only supported value.\n+\n gui.commitMsgWidth::\n \tDefines how wide the commit message window is in the\n \tlinkgit:git-gui[1]. \"75\" is the default.\ndiff --git a/gpg-interface.c b/gpg-interface.c\nindex 09ddfbc26..b39a27980 100644\n--- a/gpg-interface.c\n+++ b/gpg-interface.c\n@@ -7,6 +7,7 @@\n #include \"tempfile.h\"\n \n static char *configured_signing_key;\n+static const char *gpg_format = \"openpgp\";\n static const char *gpg_program = \"gpg\";\n \n #define PGP_SIGNATURE \"-----BEGIN PGP SIGNATURE-----\"\n@@ -138,6 +139,15 @@ int git_gpg_config(const char *var, const char *value, void *cb)\n \t\treturn 0;\n \t}\n \n+\tif (!strcmp(var, \"gpg.format\")) {\n+\t\tif (!value)\n+\t\t\treturn config_error_nonbool(var);\n+\t\tif (strcmp(value, \"openpgp\"))\n+\t\t\treturn error(\"unsupported value for %s: %s\",\n+\t\t\t\t     var, value);\n+\t\treturn git_config_string(&gpg_format, var, value);\n+\t}\n+\n \tif (!strcmp(var, \"gpg.program\")) {\n \t\tif (!value)\n \t\t\treturn config_error_nonbool(var);\n-- \n2.16.4\n\n"},{"id":"352782","messageId":"74d979ec0779b60d04e5dc7d2351783451e30eb4.1531831244.git.henning.schild@siemens.com","threadId":"48897","inReplyTo":"cover.1531831244.git.henning.schild@siemens.com","subject":"[PATCH v4 7/7] gpg-interface t: extend the existing GPG tests with GPGSM","fromName":"Henning Schild","fromEmail":"henning.schild@siemens.com","sentAt":"2018-07-17T12:50:13Z","receivedAt":"2018-07-17T12:50:45Z","isPatch":true,"sender":{"key":"henning.schild@siemens.com","avatar":"https://avatars.githubusercontent.com/u/7237877?v=4"},"body":"Add test cases to cover the new X509/gpgsm support. Most of them\nresemble existing ones. They just switch the format to x509 and set the\nsigningkey when creating signatures. Validation of signatures does not\nneed any configuration of git, it does need gpgsm to be configured to\ntrust the key(-chain).\nSeveral of the testcases build on top of existing gpg testcases.\nThe commit ships a self-signed key for committer@example.com and\nconfigures gpgsm to trust it.\n\nSigned-off-by: Henning Schild <henning.schild@siemens.com>\n---\n t/lib-gpg.sh               |  28 +++++++++++++++++++++++-\n t/lib-gpg/gpgsm-gen-key.in |   8 +++++++\n t/lib-gpg/gpgsm_cert.p12   | Bin 0 -> 2652 bytes\n t/t4202-log.sh             |  39 ++++++++++++++++++++++++++++++++++\n t/t5534-push-signed.sh     |  52 +++++++++++++++++++++++++++++++++++++++++++++\n t/t7004-tag.sh             |  13 ++++++++++++\n t/t7030-verify-tag.sh      |  33 ++++++++++++++++++++++++++++\n 7 files changed, 172 insertions(+), 1 deletion(-)\n create mode 100644 t/lib-gpg/gpgsm-gen-key.in\n create mode 100644 t/lib-gpg/gpgsm_cert.p12\n\ndiff --git a/t/lib-gpg.sh b/t/lib-gpg.sh\nindex a5d3b2cba..3fe02876c 100755\n--- a/t/lib-gpg.sh\n+++ b/t/lib-gpg.sh\n@@ -38,7 +38,33 @@ then\n \t\t\t\"$TEST_DIRECTORY\"/lib-gpg/ownertrust &&\n \t\tgpg --homedir \"${GNUPGHOME}\" </dev/null >/dev/null 2>&1 \\\n \t\t\t--sign -u committer@example.com &&\n-\t\ttest_set_prereq GPG\n+\t\ttest_set_prereq GPG &&\n+\t\t# Available key info:\n+\t\t# * see t/lib-gpg/gpgsm-gen-key.in\n+\t\t# To generate new certificate:\n+\t\t#  * no passphrase\n+\t\t#\tgpgsm --homedir /tmp/gpghome/ \\\n+\t\t#\t\t-o /tmp/gpgsm.crt.user \\\n+\t\t#\t\t--generate-key \\\n+\t\t#\t\t--batch t/lib-gpg/gpgsm-gen-key.in\n+\t\t# To import certificate:\n+\t\t#\tgpgsm --homedir /tmp/gpghome/ \\\n+\t\t#\t\t--import /tmp/gpgsm.crt.user\n+\t\t# To export into a .p12 we can later import:\n+\t\t#\tgpgsm --homedir /tmp/gpghome/ \\\n+\t\t#\t\t-o t/lib-gpg/gpgsm_cert.p12 \\\n+\t\t#\t\t--export-secret-key-p12 \"committer@example.com\"\n+\t\techo | gpgsm --homedir \"${GNUPGHOME}\" 2>/dev/null \\\n+\t\t\t--passphrase-fd 0 --pinentry-mode loopback \\\n+\t\t\t--import \"$TEST_DIRECTORY\"/lib-gpg/gpgsm_cert.p12 &&\n+\t\tgpgsm --homedir \"${GNUPGHOME}\" 2>/dev/null -K \\\n+\t\t\t| grep fingerprint: | cut -d\" \" -f4 | tr -d '\\n' > \\\n+\t\t\t${GNUPGHOME}/trustlist.txt &&\n+\t\techo \" S relax\" >> ${GNUPGHOME}/trustlist.txt &&\n+\t\t(gpgconf --kill gpg-agent >/dev/null 2>&1 || : ) &&\n+\t\techo hello | gpgsm --homedir \"${GNUPGHOME}\" >/dev/null \\\n+\t\t\t-u committer@example.com -o /dev/null --sign - 2>&1 &&\n+\t\ttest_set_prereq GPGSM\n \t\t;;\n \tesac\n fi\ndiff --git a/t/lib-gpg/gpgsm-gen-key.in b/t/lib-gpg/gpgsm-gen-key.in\nnew file mode 100644\nindex 000000000..a7fd87c06\n--- /dev/null\n+++ b/t/lib-gpg/gpgsm-gen-key.in\n@@ -0,0 +1,8 @@\n+Key-Type: RSA\n+Key-Length: 2048\n+Key-Usage: sign\n+Serial: random\n+Name-DN: CN=C O Mitter, O=Example, SN=C O, GN=Mitter\n+Name-Email: committer@example.com\n+Not-Before: 1970-01-01 00:00:00\n+Not-After: 3000-01-01 00:00:00\ndiff --git a/t/lib-gpg/gpgsm_cert.p12 b/t/lib-gpg/gpgsm_cert.p12\nnew file mode 100644\nindex 0000000000000000000000000000000000000000..94ffad0d31a3b6c4e849b29d960762e485ba7ea8\nGIT binary patch\nliteral 2652\n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\n\nliteral 0\nHcmV?d00001\n\ndiff --git a/t/t4202-log.sh b/t/t4202-log.sh\nindex 25b1f8cc7..f57781e39 100755\n--- a/t/t4202-log.sh\n+++ b/t/t4202-log.sh\n@@ -1556,12 +1556,28 @@ test_expect_success GPG 'setup signed branch' '\n \tgit commit -S -m signed_commit\n '\n \n+test_expect_success GPGSM 'setup signed branch x509' '\n+\ttest_when_finished \"git reset --hard && git checkout master\" &&\n+\tgit checkout -b signed-x509 master &&\n+\techo foo >foo &&\n+\tgit add foo &&\n+\ttest_config gpg.format x509 &&\n+\ttest_config user.signingkey $GIT_COMMITTER_EMAIL &&\n+\tgit commit -S -m signed_commit\n+'\n+\n test_expect_success GPG 'log --graph --show-signature' '\n \tgit log --graph --show-signature -n1 signed >actual &&\n \tgrep \"^| gpg: Signature made\" actual &&\n \tgrep \"^| gpg: Good signature\" actual\n '\n \n+test_expect_success GPGSM 'log --graph --show-signature x509' '\n+\tgit log --graph --show-signature -n1 signed-x509 >actual &&\n+\tgrep \"^| gpgsm: Signature made\" actual &&\n+\tgrep \"^| gpgsm: Good signature\" actual\n+'\n+\n test_expect_success GPG 'log --graph --show-signature for merged tag' '\n \ttest_when_finished \"git reset --hard && git checkout master\" &&\n \tgit checkout -b plain master &&\n@@ -1581,6 +1597,29 @@ test_expect_success GPG 'log --graph --show-signature for merged tag' '\n \tgrep \"^| | gpg: Good signature\" actual\n '\n \n+test_expect_success GPGSM 'log --graph --show-signature for merged tag x509' '\n+\ttest_when_finished \"git reset --hard && git checkout master\" &&\n+\ttest_config gpg.format x509 &&\n+\ttest_config user.signingkey $GIT_COMMITTER_EMAIL &&\n+\tgit checkout -b plain-x509 master &&\n+\techo aaa >bar &&\n+\tgit add bar &&\n+\tgit commit -m bar_commit &&\n+\tgit checkout -b tagged-x509 master &&\n+\techo bbb >baz &&\n+\tgit add baz &&\n+\tgit commit -m baz_commit &&\n+\tgit tag -s -m signed_tag_msg signed_tag_x509 &&\n+\tgit checkout plain-x509 &&\n+\tgit merge --no-ff -m msg signed_tag_x509 &&\n+\tgit log --graph --show-signature -n1 plain-x509 >actual &&\n+\tgrep \"^|\\\\\\  merged tag\" actual &&\n+\tgrep \"^| | gpgsm: Signature made\" actual &&\n+\tgrep \"^| | gpgsm: Good signature\" actual &&\n+\tgit config --unset gpg.format &&\n+\tgit config --unset user.signingkey\n+'\n+\n test_expect_success GPG '--no-show-signature overrides --show-signature' '\n \tgit log -1 --show-signature --no-show-signature signed >actual &&\n \t! grep \"^gpg:\" actual\ndiff --git a/t/t5534-push-signed.sh b/t/t5534-push-signed.sh\nindex 1cea758f7..a3a12bd05 100755\n--- a/t/t5534-push-signed.sh\n+++ b/t/t5534-push-signed.sh\n@@ -218,4 +218,56 @@ test_expect_success GPG 'fail without key and heed user.signingkey' '\n \ttest_cmp expect dst/push-cert-status\n '\n \n+test_expect_success GPGSM 'fail without key and heed user.signingkey x509' '\n+\ttest_config gpg.format x509 &&\n+\tenv | grep GIT > envfile &&\n+\tprepare_dst &&\n+\tmkdir -p dst/.git/hooks &&\n+\tgit -C dst config receive.certnonceseed sekrit &&\n+\twrite_script dst/.git/hooks/post-receive <<-\\EOF &&\n+\t# discard the update list\n+\tcat >/dev/null\n+\t# record the push certificate\n+\tif test -n \"${GIT_PUSH_CERT-}\"\n+\tthen\n+\t\tgit cat-file blob $GIT_PUSH_CERT >../push-cert\n+\tfi &&\n+\n+\tcat >../push-cert-status <<E_O_F\n+\tSIGNER=${GIT_PUSH_CERT_SIGNER-nobody}\n+\tKEY=${GIT_PUSH_CERT_KEY-nokey}\n+\tSTATUS=${GIT_PUSH_CERT_STATUS-nostatus}\n+\tNONCE_STATUS=${GIT_PUSH_CERT_NONCE_STATUS-nononcestatus}\n+\tNONCE=${GIT_PUSH_CERT_NONCE-nononce}\n+\tE_O_F\n+\n+\tEOF\n+\tunset GIT_COMMITTER_EMAIL &&\n+\tgit config user.email hasnokey@nowhere.com &&\n+\tgit config user.signingkey \"\" &&\n+\ttest_must_fail git push --signed dst noop ff +noff &&\n+\tgit config user.signingkey committer@example.com &&\n+\tgit push --signed dst noop ff +noff &&\n+\n+\t(\n+\t\tcat <<-\\EOF &&\n+\t\tSIGNER=/CN=C O Mitter/O=Example/SN=C O/GN=Mitter\n+\t\tKEY=\n+\t\tSTATUS=G\n+\t\tNONCE_STATUS=OK\n+\t\tEOF\n+\t\tsed -n -e \"s/^nonce /NONCE=/p\" -e \"/^$/q\" dst/push-cert\n+\t) >expect.in &&\n+\tkey=$(cat \"${GNUPGHOME}/trustlist.txt\" | cut -d\" \" -f1 | tr -d \":\") &&\n+\tsed -e \"s/^KEY=/KEY=${key}/\" expect.in > expect &&\n+\n+\tnoop=$(git rev-parse noop) &&\n+\tff=$(git rev-parse ff) &&\n+\tnoff=$(git rev-parse noff) &&\n+\tgrep \"$noop $ff refs/heads/ff\" dst/push-cert &&\n+\tgrep \"$noop $noff refs/heads/noff\" dst/push-cert &&\n+\ttest_cmp expect dst/push-cert-status\n+'\n+\n+\n test_done\ndiff --git a/t/t7004-tag.sh b/t/t7004-tag.sh\nindex d7b319e91..2147938aa 100755\n--- a/t/t7004-tag.sh\n+++ b/t/t7004-tag.sh\n@@ -1354,6 +1354,19 @@ test_expect_success GPG \\\n \t'test_config gpg.program echo &&\n \t test_must_fail git tag -s -m tail tag-gpg-failure'\n \n+# try to sign with bad user.signingkey\n+test_expect_success GPGSM \\\n+\t'git tag -s fails if gpgsm is misconfigured (bad key)' \\\n+\t'test_config user.signingkey BobTheMouse &&\n+\t test_config gpg.format x509 &&\n+\t test_must_fail git tag -s -m tail tag-gpg-failure'\n+\n+# try to produce invalid signature\n+test_expect_success GPGSM \\\n+\t'git tag -s fails if gpgsm is misconfigured (bad signature format)' \\\n+\t'test_config gpg.x509.program echo &&\n+\t test_config gpg.format x509 &&\n+\t test_must_fail git tag -s -m tail tag-gpg-failure'\n \n # try to verify without gpg:\n \ndiff --git a/t/t7030-verify-tag.sh b/t/t7030-verify-tag.sh\nindex 291a1e2b0..db6295d65 100755\n--- a/t/t7030-verify-tag.sh\n+++ b/t/t7030-verify-tag.sh\n@@ -41,6 +41,13 @@ test_expect_success GPG 'create signed tags' '\n \tgit tag -uB7227189 -m eighth eighth-signed-alt\n '\n \n+test_expect_success GPGSM 'create signed tags x509 ' '\n+\ttest_config gpg.format x509 &&\n+\ttest_config user.signingkey $GIT_COMMITTER_EMAIL &&\n+\techo 9 >file && test_tick && git commit -a -m \"nineth gpgsm-signed\" &&\n+\tgit tag -s -m nineth nineth-signed-x509\n+'\n+\n test_expect_success GPG 'verify and show signatures' '\n \t(\n \t\tfor tag in initial second merge fourth-signed sixth-signed seventh-signed\n@@ -72,6 +79,13 @@ test_expect_success GPG 'verify and show signatures' '\n \t)\n '\n \n+test_expect_success GPGSM 'verify and show signatures x509' '\n+\tgit verify-tag nineth-signed-x509 2>actual &&\n+\tgrep \"Good signature from\" actual &&\n+\t! grep \"BAD signature from\" actual &&\n+\techo nineth-signed-x509 OK\n+'\n+\n test_expect_success GPG 'detect fudged signature' '\n \tgit cat-file tag seventh-signed >raw &&\n \tsed -e \"/^tag / s/seventh/7th forged/\" raw >forged1 &&\n@@ -112,6 +126,12 @@ test_expect_success GPG 'verify signatures with --raw' '\n \t)\n '\n \n+test_expect_success GPGSM 'verify signatures with --raw x509' '\n+\tgit verify-tag --raw nineth-signed-x509 2>actual &&\n+\tgrep \"GOODSIG\" actual &&\n+\t! grep \"BADSIG\" actual &&\n+\techo nineth-signed-x509 OK\n+'\n test_expect_success GPG 'verify multiple tags' '\n \ttags=\"fourth-signed sixth-signed seventh-signed\" &&\n \tfor i in $tags\n@@ -125,6 +145,19 @@ test_expect_success GPG 'verify multiple tags' '\n \ttest_cmp expect.stderr actual.stderr\n '\n \n+test_expect_success GPGSM 'verify multiple tags x509' '\n+\ttags=\"seventh-signed nineth-signed-x509\" &&\n+\tfor i in $tags\n+\tdo\n+\t\tgit verify-tag -v --raw $i || return 1\n+\tdone >expect.stdout 2>expect.stderr.1 &&\n+\tgrep \"^.GNUPG:.\" <expect.stderr.1 >expect.stderr &&\n+\tgit verify-tag -v --raw $tags >actual.stdout 2>actual.stderr.1 &&\n+\tgrep \"^.GNUPG:.\" <actual.stderr.1 >actual.stderr &&\n+\ttest_cmp expect.stdout actual.stdout &&\n+\ttest_cmp expect.stderr actual.stderr\n+'\n+\n test_expect_success GPG 'verifying tag with --format' '\n \tcat >expect <<-\\EOF &&\n \ttagname : fourth-signed\n-- \n2.16.4\n\n"},{"id":"352783","messageId":"85a3ce25afbeb3eeec6b2e35adaec39f6632668e.1531831244.git.henning.schild@siemens.com","threadId":"48897","inReplyTo":"cover.1531831244.git.henning.schild@siemens.com","subject":"[PATCH v4 6/7] gpg-interface: introduce new signature format \"x509\" using gpgsm","fromName":"Henning Schild","fromEmail":"henning.schild@siemens.com","sentAt":"2018-07-17T12:50:12Z","receivedAt":"2018-07-17T12:50:55Z","isPatch":true,"sender":{"key":"henning.schild@siemens.com","avatar":"https://avatars.githubusercontent.com/u/7237877?v=4"},"body":"This commit allows git to create and check x509 type signatures using\ngpgsm.\n\nSigned-off-by: Henning Schild <henning.schild@siemens.com>\n---\n Documentation/config.txt |  5 +++--\n gpg-interface.c          | 15 +++++++++++++++\n 2 files changed, 18 insertions(+), 2 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 0e871346a..ff1d4a76c 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -1830,12 +1830,13 @@ gpg.program::\n \n gpg.format::\n \tSpecifies which key format to use when signing with `--gpg-sign`.\n-\tDefault is \"openpgp\", that is also the only supported value.\n+\tDefault is \"openpgp\" and another possible value is \"x509\".\n \n gpg.<format>.program::\n \tUse this to customize the program used for the signing format you\n \tchose. (see `gpg.program` and `gpg.format`) `gpg.program` can still\n-\tbe used as a legacy synonym for\t`gpg.openpgp.program`.\n+\tbe used as a legacy synonym for\t`gpg.openpgp.program`. The default\n+\tvalue for `gpg.x509.program` is \"gpgsm\".\n \n gui.commitMsgWidth::\n \tDefines how wide the commit message window is in the\ndiff --git a/gpg-interface.c b/gpg-interface.c\nindex a158f08c1..bb8ea668b 100644\n--- a/gpg-interface.c\n+++ b/gpg-interface.c\n@@ -24,11 +24,23 @@ static const char *openpgp_sigs[] = {\n \tNULL\n };\n \n+static const char *x509_verify_args[] = {\n+\tNULL\n+};\n+static const char *x509_sigs[] = {\n+\t\"-----BEGIN SIGNED MESSAGE-----\",\n+\tNULL\n+};\n+\n static struct gpg_format gpg_format[] = {\n \t{ .name = \"openpgp\", .program = \"gpg\",\n \t  .verify_args = openpgp_verify_args,\n \t  .sigs = openpgp_sigs\n \t},\n+\t{ .name = \"x509\", .program = \"gpgsm\",\n+\t  .verify_args = x509_verify_args,\n+\t  .sigs = x509_sigs\n+\t},\n };\n \n static struct gpg_format *use_format = &gpg_format[0];\n@@ -192,6 +204,9 @@ int git_gpg_config(const char *var, const char *value, void *cb)\n \tif (!strcmp(var, \"gpg.program\") || !strcmp(var, \"gpg.openpgp.program\"))\n \t\tfmtname = \"openpgp\";\n \n+\tif (!strcmp(var, \"gpg.x509.program\"))\n+\t\tfmtname = \"x509\";\n+\n \tif (fmtname) {\n \t\tfmt = get_format_by_name(fmtname);\n \t\treturn git_config_string(&fmt->program, var, value);\n-- \n2.16.4\n\n"},{"id":"352829","messageId":"xmqq1sc1oa2t.fsf@gitster-ct.c.googlers.com","threadId":"48897","inReplyTo":"afe7d2ef577d265ace458ef73f7a18b9ded91cd8.1531831244.git.henning.schild@siemens.com","subject":"Re: [PATCH v4 3/7] gpg-interface: introduce an abstraction for multiple gpg formats","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2018-07-17T20:56:26Z","receivedAt":"2018-07-17T20:56:32Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Henning Schild <henning.schild@siemens.com> writes:\n\n> Create a struct that holds the format details for the supported formats.\n> At the moment that is still just \"openpgp\". This commit prepares for the\n> introduction of more formats, that might use other programs and match\n> other signatures.\n>\n> Signed-off-by: Henning Schild <henning.schild@siemens.com>\n> ---\n\nI didn't spot anything questionable in this version.  Looking good.\n\n"},{"id":"352830","messageId":"xmqqwottmvhy.fsf@gitster-ct.c.googlers.com","threadId":"48897","inReplyTo":"8330bd5b90aec511e20d21cd0c466752e4ada4b1.1531831244.git.henning.schild@siemens.com","subject":"Re: [PATCH v4 4/7] gpg-interface: do not hardcode the key string len anymore","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2018-07-17T20:56:41Z","receivedAt":"2018-07-17T20:56:46Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Henning Schild <henning.schild@siemens.com> writes:\n\n> gnupg does print the keyid followed by a space and the signer comes\n> next. The same pattern is also used in gpgsm, but there the key length\n> would be 40 instead of 16. Instead of hardcoding the expected length,\n> find the first space and calculate it.\n> Input that does not match the expected format will be ignored now,\n> before we jumped to found+17 which might have been behind the end of an\n> unexpected string.\n>\n> Signed-off-by: Henning Schild <henning.schild@siemens.com>\n> ---\n>  gpg-interface.c | 7 ++++---\n>  1 file changed, 4 insertions(+), 3 deletions(-)\n\nAgain, really nice.\n\n>\n> diff --git a/gpg-interface.c b/gpg-interface.c\n> index a02db7658..51cad9081 100644\n> --- a/gpg-interface.c\n> +++ b/gpg-interface.c\n> @@ -95,10 +95,11 @@ static void parse_gpg_output(struct signature_check *sigc)\n>  \t\tsigc->result = sigcheck_gpg_status[i].result;\n>  \t\t/* The trust messages are not followed by key/signer information */\n>  \t\tif (sigc->result != 'U') {\n> -\t\t\tsigc->key = xmemdupz(found, 16);\n> +\t\t\tnext = strchrnul(found, ' ');\n> +\t\t\tsigc->key = xmemdupz(found, next - found);\n>  \t\t\t/* The ERRSIG message is not followed by signer information */\n> -\t\t\tif (sigc-> result != 'E') {\n> -\t\t\t\tfound += 17;\n> +\t\t\tif (*next && sigc-> result != 'E') {\n> +\t\t\t\tfound = next + 1;\n>  \t\t\t\tnext = strchrnul(found, '\\n');\n>  \t\t\t\tsigc->signer = xmemdupz(found, next - found);\n>  \t\t\t}\n"},{"id":"352833","messageId":"xmqqefg1mtvr.fsf@gitster-ct.c.googlers.com","threadId":"48897","inReplyTo":"74d979ec0779b60d04e5dc7d2351783451e30eb4.1531831244.git.henning.schild@siemens.com","subject":"Re: [PATCH v4 7/7] gpg-interface t: extend the existing GPG tests with GPGSM","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2018-07-17T21:31:36Z","receivedAt":"2018-07-17T21:31:42Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Henning Schild <henning.schild@siemens.com> writes:\n\n> diff --git a/t/lib-gpg.sh b/t/lib-gpg.sh\n> index a5d3b2cba..3fe02876c 100755\n> --- a/t/lib-gpg.sh\n> +++ b/t/lib-gpg.sh\n> @@ -38,7 +38,33 @@ then\n>  \t\t\t\"$TEST_DIRECTORY\"/lib-gpg/ownertrust &&\n>  \t\tgpg --homedir \"${GNUPGHOME}\" </dev/null >/dev/null 2>&1 \\\n>  \t\t\t--sign -u committer@example.com &&\n> -\t\ttest_set_prereq GPG\n> +\t\ttest_set_prereq GPG &&\n\nWe do not mind making GPGSM dependent on GPG, hence this && is justified.\n\n> +\t\t# Available key info:\n> +\t\t# * see t/lib-gpg/gpgsm-gen-key.in\n> +\t\t# To generate new certificate:\n> +\t\t#  * no passphrase\n> +\t\t#\tgpgsm --homedir /tmp/gpghome/ \\\n> +\t\t#\t\t-o /tmp/gpgsm.crt.user \\\n> +\t\t#\t\t--generate-key \\\n> +\t\t#\t\t--batch t/lib-gpg/gpgsm-gen-key.in\n> +\t\t# To import certificate:\n> +\t\t#\tgpgsm --homedir /tmp/gpghome/ \\\n> +\t\t#\t\t--import /tmp/gpgsm.crt.user\n> +\t\t# To export into a .p12 we can later import:\n> +\t\t#\tgpgsm --homedir /tmp/gpghome/ \\\n> +\t\t#\t\t-o t/lib-gpg/gpgsm_cert.p12 \\\n> +\t\t#\t\t--export-secret-key-p12 \"committer@example.com\"\n> +\t\techo | gpgsm --homedir \"${GNUPGHOME}\" 2>/dev/null \\\n> +\t\t\t--passphrase-fd 0 --pinentry-mode loopback \\\n> +\t\t\t--import \"$TEST_DIRECTORY\"/lib-gpg/gpgsm_cert.p12 &&\n> +\t\tgpgsm --homedir \"${GNUPGHOME}\" 2>/dev/null -K \\\n> +\t\t\t| grep fingerprint: | cut -d\" \" -f4 | tr -d '\\n' > \\\n> +\t\t\t${GNUPGHOME}/trustlist.txt &&\n> +\t\techo \" S relax\" >> ${GNUPGHOME}/trustlist.txt &&\n> +\t\t(gpgconf --kill gpg-agent >/dev/null 2>&1 || : ) &&\n> +\t\techo hello | gpgsm --homedir \"${GNUPGHOME}\" >/dev/null \\\n> +\t\t\t-u committer@example.com -o /dev/null --sign - 2>&1 &&\n> +\t\ttest_set_prereq GPGSM\n\nAnd when any of the above fails, we refrain from setting GPGSM\nprereq.  Otherwise we are prepared to perform tests with gpgsm\nand get the prereq.\n\n> diff --git a/t/t4202-log.sh b/t/t4202-log.sh\n> index 25b1f8cc7..f57781e39 100755\n> --- a/t/t4202-log.sh\n> +++ b/t/t4202-log.sh\n> @@ -1556,12 +1556,28 @@ test_expect_success GPG 'setup signed branch' '\n>  \tgit commit -S -m signed_commit\n>  '\n>  \n> +test_expect_success GPGSM 'setup signed branch x509' '\n> +\ttest_when_finished \"git reset --hard && git checkout master\" &&\n> +\tgit checkout -b signed-x509 master &&\n> +\techo foo >foo &&\n> +\tgit add foo &&\n> +\ttest_config gpg.format x509 &&\n> +\ttest_config user.signingkey $GIT_COMMITTER_EMAIL &&\n> +\tgit commit -S -m signed_commit\n> +'\n\nOK.\n\n> +test_expect_success GPGSM 'log --graph --show-signature x509' '\n> +\tgit log --graph --show-signature -n1 signed-x509 >actual &&\n> +\tgrep \"^| gpgsm: Signature made\" actual &&\n> +\tgrep \"^| gpgsm: Good signature\" actual\n> +'\n\nOK.\n\n> @@ -1581,6 +1597,29 @@ test_expect_success GPG 'log --graph --show-signature for merged tag' '\n>  \tgrep \"^| | gpg: Good signature\" actual\n>  '\n>  \n> +test_expect_success GPGSM 'log --graph --show-signature for merged tag x509' '\n> +\ttest_when_finished \"git reset --hard && git checkout master\" &&\n> +\ttest_config gpg.format x509 &&\n> +\ttest_config user.signingkey $GIT_COMMITTER_EMAIL &&\n> +\tgit checkout -b plain-x509 master &&\n> +\techo aaa >bar &&\n> +\tgit add bar &&\n> +\tgit commit -m bar_commit &&\n> +\tgit checkout -b tagged-x509 master &&\n> +\techo bbb >baz &&\n> +\tgit add baz &&\n> +\tgit commit -m baz_commit &&\n> +\tgit tag -s -m signed_tag_msg signed_tag_x509 &&\n> +\tgit checkout plain-x509 &&\n> +\tgit merge --no-ff -m msg signed_tag_x509 &&\n> +\tgit log --graph --show-signature -n1 plain-x509 >actual &&\n> +\tgrep \"^|\\\\\\  merged tag\" actual &&\n> +\tgrep \"^| | gpgsm: Signature made\" actual &&\n> +\tgrep \"^| | gpgsm: Good signature\" actual &&\n> +\tgit config --unset gpg.format &&\n> +\tgit config --unset user.signingkey\n\nYou are using test_config early enough in this test; doesn't that\ntake care of the last two steps for you, even when an earlier step\nfailed?  If that is the case, then remove the last two line (and &&\nat the end of the line before).\n\n> diff --git a/t/t5534-push-signed.sh b/t/t5534-push-signed.sh\n> index 1cea758f7..a3a12bd05 100755\n> --- a/t/t5534-push-signed.sh\n> +++ b/t/t5534-push-signed.sh\n> @@ -218,4 +218,56 @@ test_expect_success GPG 'fail without key and heed user.signingkey' '\n>  \ttest_cmp expect dst/push-cert-status\n>  '\n>  \n> +test_expect_success GPGSM 'fail without key and heed user.signingkey x509' '\n> +\ttest_config gpg.format x509 &&\n> +\tenv | grep GIT > envfile &&\n\nThe \"envfile\" is unused, no?  Remove this line.\n\n> +\tprepare_dst &&\n> +\tmkdir -p dst/.git/hooks &&\n> +\tgit -C dst config receive.certnonceseed sekrit &&\n> +\twrite_script dst/.git/hooks/post-receive <<-\\EOF &&\n> +\t# discard the update list\n> +\tcat >/dev/null\n> +\t# record the push certificate\n> +\tif test -n \"${GIT_PUSH_CERT-}\"\n> +\tthen\n> +\t\tgit cat-file blob $GIT_PUSH_CERT >../push-cert\n> +\tfi &&\n> +\n> +\tcat >../push-cert-status <<E_O_F\n> +\tSIGNER=${GIT_PUSH_CERT_SIGNER-nobody}\n> +\tKEY=${GIT_PUSH_CERT_KEY-nokey}\n> +\tSTATUS=${GIT_PUSH_CERT_STATUS-nostatus}\n> +\tNONCE_STATUS=${GIT_PUSH_CERT_NONCE_STATUS-nononcestatus}\n> +\tNONCE=${GIT_PUSH_CERT_NONCE-nononce}\n> +\tE_O_F\n> +\n> +\tEOF\n\nOK, so up to this are what is done by post-receive, including the\noverwriting of ../push-cert (which is one level above the receiving\nrepository's .git/, i.e. dst/push-cert) and ../push-cert-status.\n\n> +\tunset GIT_COMMITTER_EMAIL &&\n> +\tgit config user.email hasnokey@nowhere.com &&\n> +\tgit config user.signingkey \"\" &&\n> +\ttest_must_fail git push --signed dst noop ff +noff &&\n\nThis is OK for a test that is known to be always at the end, but\nalso forbids others to further update this script to add more tests\nat the end, as the standard setting of environment is blown away\n(the config is probably OK, but test_config to arrange them to be\ncleaned up would have been nicer), which is not very nice.  I think\nit should be easy to fix it when it becomes necessary, but at the\nsame time if it is easy to fix, then probably we shouldn't introduce\na breakage in the first place, so I am on the fence.\n\n> +\tgit config user.signingkey committer@example.com &&\n> +\tgit push --signed dst noop ff +noff &&\n\nSo,... this is run without resetting user.email and demonstrates\nthat signingkey is the only thing that matters, which makes sense.\n\n> +\t(\n> +\t\tcat <<-\\EOF &&\n> +\t\tSIGNER=/CN=C O Mitter/O=Example/SN=C O/GN=Mitter\n> +\t\tKEY=\n> +\t\tSTATUS=G\n> +\t\tNONCE_STATUS=OK\n> +\t\tEOF\n> +\t\tsed -n -e \"s/^nonce /NONCE=/p\" -e \"/^$/q\" dst/push-cert\n> +\t) >expect.in &&\n> +\tkey=$(cat \"${GNUPGHOME}/trustlist.txt\" | cut -d\" \" -f1 | tr -d \":\") &&\n> +\tsed -e \"s/^KEY=/KEY=${key}/\" expect.in > expect &&\n\ns/> expect/>expect/;\n\n> +\tnoop=$(git rev-parse noop) &&\n> +\tff=$(git rev-parse ff) &&\n> +\tnoff=$(git rev-parse noff) &&\n> +\tgrep \"$noop $ff refs/heads/ff\" dst/push-cert &&\n> +\tgrep \"$noop $noff refs/heads/noff\" dst/push-cert &&\n> +\ttest_cmp expect dst/push-cert-status\n> +'\n> +\n> +\n>  test_done\n> diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh\n> index d7b319e91..2147938aa 100755\n> --- a/t/t7004-tag.sh\n> +++ b/t/t7004-tag.sh\n> @@ -1354,6 +1354,19 @@ test_expect_success GPG \\\n>  \t'test_config gpg.program echo &&\n>  \t test_must_fail git tag -s -m tail tag-gpg-failure'\n>  \n> +# try to sign with bad user.signingkey\n> +test_expect_success GPGSM \\\n> +\t'git tag -s fails if gpgsm is misconfigured (bad key)' \\\n> +\t'test_config user.signingkey BobTheMouse &&\n> +\t test_config gpg.format x509 &&\n> +\t test_must_fail git tag -s -m tail tag-gpg-failure'\n> +\n> +# try to produce invalid signature\n> +test_expect_success GPGSM \\\n> +\t'git tag -s fails if gpgsm is misconfigured (bad signature format)' \\\n> +\t'test_config gpg.x509.program echo &&\n> +\t test_config gpg.format x509 &&\n> +\t test_must_fail git tag -s -m tail tag-gpg-failure'\n\nI can see that it is a gpgsm parallel of the earlier test we can see\nin the precontext of this hunk done for gpg, but how does the last\none (and the original this one was modeled after) fail?\n\nWe say \"echo\" is the program that signs for the chosen format, \"tag\n-s\" tries to run \"echo\" instead of \"gpgsm\" with \"--status-fd=2\n-bsau\" or whatever args we usually give, and...?\n\nI would guess you would either get \"I don't know what you wanted me\nto do with --status-fd=2 option, I am erroring out\" from \"echo\", or\nthe \"echo\" command exiting without consuming any input, causing the\nfeeder in \"tag -s\" to get SIGPIPE (or write(2) error), but the latter\nhappens only when the payload to be signed is large enough.  On a\nplatform whose \"echo\" pays no attention to unknown option, \"echo\"\nitself may not even error out.  And then we try to read from \"echo\"\nand we do not get anything (which is expected).  \n\nAnd then who in \"git tag -s\" notice the breakage?\n\n\t... goes and looks at gpg-interface.c::sign_buffer() ...\n\nAh, we check the status-fd output for \"[GnuPG:] SIG_CREATED\", which\nwould never happen if we are talking to \"echo\".  OK, that is how\nthis thing is expected to fail.\n\nWhat I have been getting at is if this is really trying to trigger\nthe \"(bad signature format)\" breakage.  The test uses a wrong\nprogram to simulate the case where a configured gpg/gpgsm failed to\nreport \"SIG_CREATED\".  \"bad signature format\" does not sound exactly \nlike that, but you inherited the badness from the original, so let's\nleave it as is.\n\nThanks.  Modulo a few nits I pointed out above, buried in all the\nother good bits, this looks reasonable to me.\n\n"},{"id":"352834","messageId":"xmqq7eltmtv7.fsf@gitster-ct.c.googlers.com","threadId":"48897","inReplyTo":"2f806c4fa4454af59344f0f0e77d1ae8048aa841.1531831244.git.henning.schild@siemens.com","subject":"Re: [PATCH v4 2/7] t/t7510: check the validation of the new config gpg.format","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2018-07-17T21:31:56Z","receivedAt":"2018-07-17T21:32:01Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Henning Schild <henning.schild@siemens.com> writes:\n\n> Test setting gpg.format to both invalid and valid values.\n>\n> Signed-off-by: Henning Schild <henning.schild@siemens.com>\n> ---\n>  t/t7510-signed-commit.sh | 9 +++++++++\n>  1 file changed, 9 insertions(+)\n>\n> diff --git a/t/t7510-signed-commit.sh b/t/t7510-signed-commit.sh\n> index 6e2015ed9..7bdad570c 100755\n> --- a/t/t7510-signed-commit.sh\n> +++ b/t/t7510-signed-commit.sh\n> @@ -227,4 +227,13 @@ test_expect_success GPG 'log.showsignature behaves like --show-signature' '\n>  \tgrep \"gpg: Good signature\" actual\n>  '\n>  \n> +test_expect_success GPG 'check config gpg.format values' '\n> +\ttest_config gpg.format openpgp &&\n> +\tgit commit -S --amend -m \"success\" &&\n> +\ttest_config gpg.format OpEnPgP &&\n> +\ttest_must_fail git commit -S --amend -m \"fail\" &&\n\nThis second one is a good demonstration that the value for this\nvariable is case sensitive.\n\n> +\ttest_config gpg.format malformed &&\n> +\ttest_must_fail git commit -S --amend -m \"fail\"\n\nAnd there is no longer a good reason to try another one.  Let's drop\nthis last/third case.\n\n> +'\n> +\n>  test_done\n"},{"id":"352850","messageId":"20180718093010.29651-1-henning.schild@siemens.com","threadId":"48897","inReplyTo":"2f806c4fa4454af59344f0f0e77d1ae8048aa841.1531831244.git.henning.schild@siemens.com","subject":"[PATCH v5 2/7] t/t7510: check the validation of the new config gpg.format","fromName":"Henning Schild","fromEmail":"henning.schild@siemens.com","sentAt":"2018-07-18T09:30:10Z","receivedAt":"2018-07-18T09:30:36Z","isPatch":true,"sender":{"key":"henning.schild@siemens.com","avatar":"https://avatars.githubusercontent.com/u/7237877?v=4"},"body":"Test setting gpg.format to both invalid and valid values.\n\nSigned-off-by: Henning Schild <henning.schild@siemens.com>\n---\n t/t7510-signed-commit.sh | 7 +++++++\n 1 file changed, 7 insertions(+)\n\ndiff --git a/t/t7510-signed-commit.sh b/t/t7510-signed-commit.sh\nindex 6e2015ed9..4e37ff8f1 100755\n--- a/t/t7510-signed-commit.sh\n+++ b/t/t7510-signed-commit.sh\n@@ -227,4 +227,11 @@ test_expect_success GPG 'log.showsignature behaves like --show-signature' '\n \tgrep \"gpg: Good signature\" actual\n '\n \n+test_expect_success GPG 'check config gpg.format values' '\n+\ttest_config gpg.format openpgp &&\n+\tgit commit -S --amend -m \"success\" &&\n+\ttest_config gpg.format OpEnPgP &&\n+\ttest_must_fail git commit -S --amend -m \"fail\"\n+'\n+\n test_done\n-- \n2.16.4\n\n"},{"id":"352851","messageId":"20180718093112.29783-1-henning.schild@siemens.com","threadId":"48897","inReplyTo":"74d979ec0779b60d04e5dc7d2351783451e30eb4.1531831244.git.henning.schild@siemens.com","subject":"[PATCH v5 7/7] gpg-interface t: extend the existing GPG tests with GPGSM","fromName":"Henning Schild","fromEmail":"henning.schild@siemens.com","sentAt":"2018-07-18T09:31:12Z","receivedAt":"2018-07-18T09:31:41Z","isPatch":true,"sender":{"key":"henning.schild@siemens.com","avatar":"https://avatars.githubusercontent.com/u/7237877?v=4"},"body":"Add test cases to cover the new X509/gpgsm support. Most of them\nresemble existing ones. They just switch the format to x509 and set the\nsigningkey when creating signatures. Validation of signatures does not\nneed any configuration of git, it does need gpgsm to be configured to\ntrust the key(-chain).\nSeveral of the testcases build on top of existing gpg testcases.\nThe commit ships a self-signed key for committer@example.com and\nconfigures gpgsm to trust it.\n\nSigned-off-by: Henning Schild <henning.schild@siemens.com>\n---\n t/lib-gpg.sh               |  28 ++++++++++++++++++++++++-\n t/lib-gpg/gpgsm-gen-key.in |   8 +++++++\n t/lib-gpg/gpgsm_cert.p12   | Bin 0 -> 2652 bytes\n t/t4202-log.sh             |  37 ++++++++++++++++++++++++++++++++\n t/t5534-push-signed.sh     |  51 +++++++++++++++++++++++++++++++++++++++++++++\n t/t7004-tag.sh             |  13 ++++++++++++\n t/t7030-verify-tag.sh      |  33 +++++++++++++++++++++++++++++\n 7 files changed, 169 insertions(+), 1 deletion(-)\n create mode 100644 t/lib-gpg/gpgsm-gen-key.in\n create mode 100644 t/lib-gpg/gpgsm_cert.p12\n\ndiff --git a/t/lib-gpg.sh b/t/lib-gpg.sh\nindex a5d3b2cba..3fe02876c 100755\n--- a/t/lib-gpg.sh\n+++ b/t/lib-gpg.sh\n@@ -38,7 +38,33 @@ then\n \t\t\t\"$TEST_DIRECTORY\"/lib-gpg/ownertrust &&\n \t\tgpg --homedir \"${GNUPGHOME}\" </dev/null >/dev/null 2>&1 \\\n \t\t\t--sign -u committer@example.com &&\n-\t\ttest_set_prereq GPG\n+\t\ttest_set_prereq GPG &&\n+\t\t# Available key info:\n+\t\t# * see t/lib-gpg/gpgsm-gen-key.in\n+\t\t# To generate new certificate:\n+\t\t#  * no passphrase\n+\t\t#\tgpgsm --homedir /tmp/gpghome/ \\\n+\t\t#\t\t-o /tmp/gpgsm.crt.user \\\n+\t\t#\t\t--generate-key \\\n+\t\t#\t\t--batch t/lib-gpg/gpgsm-gen-key.in\n+\t\t# To import certificate:\n+\t\t#\tgpgsm --homedir /tmp/gpghome/ \\\n+\t\t#\t\t--import /tmp/gpgsm.crt.user\n+\t\t# To export into a .p12 we can later import:\n+\t\t#\tgpgsm --homedir /tmp/gpghome/ \\\n+\t\t#\t\t-o t/lib-gpg/gpgsm_cert.p12 \\\n+\t\t#\t\t--export-secret-key-p12 \"committer@example.com\"\n+\t\techo | gpgsm --homedir \"${GNUPGHOME}\" 2>/dev/null \\\n+\t\t\t--passphrase-fd 0 --pinentry-mode loopback \\\n+\t\t\t--import \"$TEST_DIRECTORY\"/lib-gpg/gpgsm_cert.p12 &&\n+\t\tgpgsm --homedir \"${GNUPGHOME}\" 2>/dev/null -K \\\n+\t\t\t| grep fingerprint: | cut -d\" \" -f4 | tr -d '\\n' > \\\n+\t\t\t${GNUPGHOME}/trustlist.txt &&\n+\t\techo \" S relax\" >> ${GNUPGHOME}/trustlist.txt &&\n+\t\t(gpgconf --kill gpg-agent >/dev/null 2>&1 || : ) &&\n+\t\techo hello | gpgsm --homedir \"${GNUPGHOME}\" >/dev/null \\\n+\t\t\t-u committer@example.com -o /dev/null --sign - 2>&1 &&\n+\t\ttest_set_prereq GPGSM\n \t\t;;\n \tesac\n fi\ndiff --git a/t/lib-gpg/gpgsm-gen-key.in b/t/lib-gpg/gpgsm-gen-key.in\nnew file mode 100644\nindex 000000000..a7fd87c06\n--- /dev/null\n+++ b/t/lib-gpg/gpgsm-gen-key.in\n@@ -0,0 +1,8 @@\n+Key-Type: RSA\n+Key-Length: 2048\n+Key-Usage: sign\n+Serial: random\n+Name-DN: CN=C O Mitter, O=Example, SN=C O, GN=Mitter\n+Name-Email: committer@example.com\n+Not-Before: 1970-01-01 00:00:00\n+Not-After: 3000-01-01 00:00:00\ndiff --git a/t/lib-gpg/gpgsm_cert.p12 b/t/lib-gpg/gpgsm_cert.p12\nnew file mode 100644\nindex 0000000000000000000000000000000000000000..94ffad0d31a3b6c4e849b29d960762e485ba7ea8\nGIT binary patch\nliteral 2652\n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\n\nliteral 0\nHcmV?d00001\n\ndiff --git a/t/t4202-log.sh b/t/t4202-log.sh\nindex 25b1f8cc7..05d3707e3 100755\n--- a/t/t4202-log.sh\n+++ b/t/t4202-log.sh\n@@ -1556,12 +1556,28 @@ test_expect_success GPG 'setup signed branch' '\n \tgit commit -S -m signed_commit\n '\n \n+test_expect_success GPGSM 'setup signed branch x509' '\n+\ttest_when_finished \"git reset --hard && git checkout master\" &&\n+\tgit checkout -b signed-x509 master &&\n+\techo foo >foo &&\n+\tgit add foo &&\n+\ttest_config gpg.format x509 &&\n+\ttest_config user.signingkey $GIT_COMMITTER_EMAIL &&\n+\tgit commit -S -m signed_commit\n+'\n+\n test_expect_success GPG 'log --graph --show-signature' '\n \tgit log --graph --show-signature -n1 signed >actual &&\n \tgrep \"^| gpg: Signature made\" actual &&\n \tgrep \"^| gpg: Good signature\" actual\n '\n \n+test_expect_success GPGSM 'log --graph --show-signature x509' '\n+\tgit log --graph --show-signature -n1 signed-x509 >actual &&\n+\tgrep \"^| gpgsm: Signature made\" actual &&\n+\tgrep \"^| gpgsm: Good signature\" actual\n+'\n+\n test_expect_success GPG 'log --graph --show-signature for merged tag' '\n \ttest_when_finished \"git reset --hard && git checkout master\" &&\n \tgit checkout -b plain master &&\n@@ -1581,6 +1597,27 @@ test_expect_success GPG 'log --graph --show-signature for merged tag' '\n \tgrep \"^| | gpg: Good signature\" actual\n '\n \n+test_expect_success GPGSM 'log --graph --show-signature for merged tag x509' '\n+\ttest_when_finished \"git reset --hard && git checkout master\" &&\n+\ttest_config gpg.format x509 &&\n+\ttest_config user.signingkey $GIT_COMMITTER_EMAIL &&\n+\tgit checkout -b plain-x509 master &&\n+\techo aaa >bar &&\n+\tgit add bar &&\n+\tgit commit -m bar_commit &&\n+\tgit checkout -b tagged-x509 master &&\n+\techo bbb >baz &&\n+\tgit add baz &&\n+\tgit commit -m baz_commit &&\n+\tgit tag -s -m signed_tag_msg signed_tag_x509 &&\n+\tgit checkout plain-x509 &&\n+\tgit merge --no-ff -m msg signed_tag_x509 &&\n+\tgit log --graph --show-signature -n1 plain-x509 >actual &&\n+\tgrep \"^|\\\\\\  merged tag\" actual &&\n+\tgrep \"^| | gpgsm: Signature made\" actual &&\n+\tgrep \"^| | gpgsm: Good signature\" actual\n+'\n+\n test_expect_success GPG '--no-show-signature overrides --show-signature' '\n \tgit log -1 --show-signature --no-show-signature signed >actual &&\n \t! grep \"^gpg:\" actual\ndiff --git a/t/t5534-push-signed.sh b/t/t5534-push-signed.sh\nindex 1cea758f7..0cb88aa6f 100755\n--- a/t/t5534-push-signed.sh\n+++ b/t/t5534-push-signed.sh\n@@ -218,4 +218,55 @@ test_expect_success GPG 'fail without key and heed user.signingkey' '\n \ttest_cmp expect dst/push-cert-status\n '\n \n+test_expect_success GPGSM 'fail without key and heed user.signingkey x509' '\n+\ttest_config gpg.format x509 &&\n+\tprepare_dst &&\n+\tmkdir -p dst/.git/hooks &&\n+\tgit -C dst config receive.certnonceseed sekrit &&\n+\twrite_script dst/.git/hooks/post-receive <<-\\EOF &&\n+\t# discard the update list\n+\tcat >/dev/null\n+\t# record the push certificate\n+\tif test -n \"${GIT_PUSH_CERT-}\"\n+\tthen\n+\t\tgit cat-file blob $GIT_PUSH_CERT >../push-cert\n+\tfi &&\n+\n+\tcat >../push-cert-status <<E_O_F\n+\tSIGNER=${GIT_PUSH_CERT_SIGNER-nobody}\n+\tKEY=${GIT_PUSH_CERT_KEY-nokey}\n+\tSTATUS=${GIT_PUSH_CERT_STATUS-nostatus}\n+\tNONCE_STATUS=${GIT_PUSH_CERT_NONCE_STATUS-nononcestatus}\n+\tNONCE=${GIT_PUSH_CERT_NONCE-nononce}\n+\tE_O_F\n+\n+\tEOF\n+\tunset GIT_COMMITTER_EMAIL &&\n+\ttest_config user.email hasnokey@nowhere.com &&\n+\ttest_config user.signingkey \"\" &&\n+\ttest_must_fail git push --signed dst noop ff +noff &&\n+\ttest_config user.signingkey committer@example.com &&\n+\tgit push --signed dst noop ff +noff &&\n+\n+\t(\n+\t\tcat <<-\\EOF &&\n+\t\tSIGNER=/CN=C O Mitter/O=Example/SN=C O/GN=Mitter\n+\t\tKEY=\n+\t\tSTATUS=G\n+\t\tNONCE_STATUS=OK\n+\t\tEOF\n+\t\tsed -n -e \"s/^nonce /NONCE=/p\" -e \"/^$/q\" dst/push-cert\n+\t) >expect.in &&\n+\tkey=$(cat \"${GNUPGHOME}/trustlist.txt\" | cut -d\" \" -f1 | tr -d \":\") &&\n+\tsed -e \"s/^KEY=/KEY=${key}/\" expect.in >expect &&\n+\n+\tnoop=$(git rev-parse noop) &&\n+\tff=$(git rev-parse ff) &&\n+\tnoff=$(git rev-parse noff) &&\n+\tgrep \"$noop $ff refs/heads/ff\" dst/push-cert &&\n+\tgrep \"$noop $noff refs/heads/noff\" dst/push-cert &&\n+\ttest_cmp expect dst/push-cert-status\n+'\n+\n+\n test_done\ndiff --git a/t/t7004-tag.sh b/t/t7004-tag.sh\nindex d7b319e91..2147938aa 100755\n--- a/t/t7004-tag.sh\n+++ b/t/t7004-tag.sh\n@@ -1354,6 +1354,19 @@ test_expect_success GPG \\\n \t'test_config gpg.program echo &&\n \t test_must_fail git tag -s -m tail tag-gpg-failure'\n \n+# try to sign with bad user.signingkey\n+test_expect_success GPGSM \\\n+\t'git tag -s fails if gpgsm is misconfigured (bad key)' \\\n+\t'test_config user.signingkey BobTheMouse &&\n+\t test_config gpg.format x509 &&\n+\t test_must_fail git tag -s -m tail tag-gpg-failure'\n+\n+# try to produce invalid signature\n+test_expect_success GPGSM \\\n+\t'git tag -s fails if gpgsm is misconfigured (bad signature format)' \\\n+\t'test_config gpg.x509.program echo &&\n+\t test_config gpg.format x509 &&\n+\t test_must_fail git tag -s -m tail tag-gpg-failure'\n \n # try to verify without gpg:\n \ndiff --git a/t/t7030-verify-tag.sh b/t/t7030-verify-tag.sh\nindex 291a1e2b0..db6295d65 100755\n--- a/t/t7030-verify-tag.sh\n+++ b/t/t7030-verify-tag.sh\n@@ -41,6 +41,13 @@ test_expect_success GPG 'create signed tags' '\n \tgit tag -uB7227189 -m eighth eighth-signed-alt\n '\n \n+test_expect_success GPGSM 'create signed tags x509 ' '\n+\ttest_config gpg.format x509 &&\n+\ttest_config user.signingkey $GIT_COMMITTER_EMAIL &&\n+\techo 9 >file && test_tick && git commit -a -m \"nineth gpgsm-signed\" &&\n+\tgit tag -s -m nineth nineth-signed-x509\n+'\n+\n test_expect_success GPG 'verify and show signatures' '\n \t(\n \t\tfor tag in initial second merge fourth-signed sixth-signed seventh-signed\n@@ -72,6 +79,13 @@ test_expect_success GPG 'verify and show signatures' '\n \t)\n '\n \n+test_expect_success GPGSM 'verify and show signatures x509' '\n+\tgit verify-tag nineth-signed-x509 2>actual &&\n+\tgrep \"Good signature from\" actual &&\n+\t! grep \"BAD signature from\" actual &&\n+\techo nineth-signed-x509 OK\n+'\n+\n test_expect_success GPG 'detect fudged signature' '\n \tgit cat-file tag seventh-signed >raw &&\n \tsed -e \"/^tag / s/seventh/7th forged/\" raw >forged1 &&\n@@ -112,6 +126,12 @@ test_expect_success GPG 'verify signatures with --raw' '\n \t)\n '\n \n+test_expect_success GPGSM 'verify signatures with --raw x509' '\n+\tgit verify-tag --raw nineth-signed-x509 2>actual &&\n+\tgrep \"GOODSIG\" actual &&\n+\t! grep \"BADSIG\" actual &&\n+\techo nineth-signed-x509 OK\n+'\n test_expect_success GPG 'verify multiple tags' '\n \ttags=\"fourth-signed sixth-signed seventh-signed\" &&\n \tfor i in $tags\n@@ -125,6 +145,19 @@ test_expect_success GPG 'verify multiple tags' '\n \ttest_cmp expect.stderr actual.stderr\n '\n \n+test_expect_success GPGSM 'verify multiple tags x509' '\n+\ttags=\"seventh-signed nineth-signed-x509\" &&\n+\tfor i in $tags\n+\tdo\n+\t\tgit verify-tag -v --raw $i || return 1\n+\tdone >expect.stdout 2>expect.stderr.1 &&\n+\tgrep \"^.GNUPG:.\" <expect.stderr.1 >expect.stderr &&\n+\tgit verify-tag -v --raw $tags >actual.stdout 2>actual.stderr.1 &&\n+\tgrep \"^.GNUPG:.\" <actual.stderr.1 >actual.stderr &&\n+\ttest_cmp expect.stdout actual.stdout &&\n+\ttest_cmp expect.stderr actual.stderr\n+'\n+\n test_expect_success GPG 'verifying tag with --format' '\n \tcat >expect <<-\\EOF &&\n \ttagname : fourth-signed\n-- \n2.16.4\n\n"},{"id":"352853","messageId":"20180718123614.1807a948@md1pvb1c.ad001.siemens.net","threadId":"48897","inReplyTo":"xmqq7eltmtv7.fsf@gitster-ct.c.googlers.com","subject":"Re: [PATCH v4 2/7] t/t7510: check the validation of the new config gpg.format","fromName":"Henning Schild","fromEmail":"henning.schild@siemens.com","sentAt":"2018-07-18T10:36:14Z","receivedAt":"2018-07-18T10:36:41Z","isPatch":true,"sender":{"key":"henning.schild@siemens.com","avatar":"https://avatars.githubusercontent.com/u/7237877?v=4"},"body":"Am Tue, 17 Jul 2018 14:31:56 -0700\nschrieb Junio C Hamano <gitster@pobox.com>:\n\n> Henning Schild <henning.schild@siemens.com> writes:\n> \n> > Test setting gpg.format to both invalid and valid values.\n> >\n> > Signed-off-by: Henning Schild <henning.schild@siemens.com>\n> > ---\n> >  t/t7510-signed-commit.sh | 9 +++++++++\n> >  1 file changed, 9 insertions(+)\n> >\n> > diff --git a/t/t7510-signed-commit.sh b/t/t7510-signed-commit.sh\n> > index 6e2015ed9..7bdad570c 100755\n> > --- a/t/t7510-signed-commit.sh\n> > +++ b/t/t7510-signed-commit.sh\n> > @@ -227,4 +227,13 @@ test_expect_success GPG 'log.showsignature\n> > behaves like --show-signature' ' grep \"gpg: Good signature\" actual\n> >  '\n> >  \n> > +test_expect_success GPG 'check config gpg.format values' '\n> > +\ttest_config gpg.format openpgp &&\n> > +\tgit commit -S --amend -m \"success\" &&\n> > +\ttest_config gpg.format OpEnPgP &&\n> > +\ttest_must_fail git commit -S --amend -m \"fail\" &&  \n> \n> This second one is a good demonstration that the value for this\n> variable is case sensitive.\n> \n> > +\ttest_config gpg.format malformed &&\n> > +\ttest_must_fail git commit -S --amend -m \"fail\"  \n> \n> And there is no longer a good reason to try another one.  Let's drop\n> this last/third case.\n\nDone.\n\nHenning\n\n> > +'\n> > +\n> >  test_done  \n\n"},{"id":"352854","messageId":"20180718123617.55acfd3b@md1pvb1c.ad001.siemens.net","threadId":"48897","inReplyTo":"xmqqefg1mtvr.fsf@gitster-ct.c.googlers.com","subject":"Re: [PATCH v4 7/7] gpg-interface t: extend the existing GPG tests with GPGSM","fromName":"Henning Schild","fromEmail":"henning.schild@siemens.com","sentAt":"2018-07-18T10:36:17Z","receivedAt":"2018-07-18T10:36:47Z","isPatch":true,"sender":{"key":"henning.schild@siemens.com","avatar":"https://avatars.githubusercontent.com/u/7237877?v=4"},"body":"Am Tue, 17 Jul 2018 14:31:36 -0700\nschrieb Junio C Hamano <gitster@pobox.com>:\n\n> Henning Schild <henning.schild@siemens.com> writes:\n> \n> > diff --git a/t/lib-gpg.sh b/t/lib-gpg.sh\n> > index a5d3b2cba..3fe02876c 100755\n> > --- a/t/lib-gpg.sh\n> > +++ b/t/lib-gpg.sh\n> > @@ -38,7 +38,33 @@ then\n> >  \t\t\t\"$TEST_DIRECTORY\"/lib-gpg/ownertrust &&\n> >  \t\tgpg --homedir \"${GNUPGHOME}\" </dev/null >/dev/null\n> > 2>&1 \\ --sign -u committer@example.com &&\n> > -\t\ttest_set_prereq GPG\n> > +\t\ttest_set_prereq GPG &&  \n> \n> We do not mind making GPGSM dependent on GPG, hence this && is\n> justified.\n> \n> > +\t\t# Available key info:\n> > +\t\t# * see t/lib-gpg/gpgsm-gen-key.in\n> > +\t\t# To generate new certificate:\n> > +\t\t#  * no passphrase\n> > +\t\t#\tgpgsm --homedir /tmp/gpghome/ \\\n> > +\t\t#\t\t-o /tmp/gpgsm.crt.user \\\n> > +\t\t#\t\t--generate-key \\\n> > +\t\t#\t\t--batch t/lib-gpg/gpgsm-gen-key.in\n> > +\t\t# To import certificate:\n> > +\t\t#\tgpgsm --homedir /tmp/gpghome/ \\\n> > +\t\t#\t\t--import /tmp/gpgsm.crt.user\n> > +\t\t# To export into a .p12 we can later import:\n> > +\t\t#\tgpgsm --homedir /tmp/gpghome/ \\\n> > +\t\t#\t\t-o t/lib-gpg/gpgsm_cert.p12 \\\n> > +\t\t#\t\t--export-secret-key-p12\n> > \"committer@example.com\"\n> > +\t\techo | gpgsm --homedir \"${GNUPGHOME}\" 2>/dev/null \\\n> > +\t\t\t--passphrase-fd 0 --pinentry-mode loopback\n> > \\\n> > +\t\t\t--import\n> > \"$TEST_DIRECTORY\"/lib-gpg/gpgsm_cert.p12 &&\n> > +\t\tgpgsm --homedir \"${GNUPGHOME}\" 2>/dev/null -K \\\n> > +\t\t\t| grep fingerprint: | cut -d\" \" -f4 | tr\n> > -d '\\n' > \\\n> > +\t\t\t${GNUPGHOME}/trustlist.txt &&\n> > +\t\techo \" S relax\" >> ${GNUPGHOME}/trustlist.txt &&\n> > +\t\t(gpgconf --kill gpg-agent >/dev/null 2>&1 || : ) &&\n> > +\t\techo hello | gpgsm --homedir \"${GNUPGHOME}\"\n> > >/dev/null \\\n> > +\t\t\t-u committer@example.com -o /dev/null\n> > --sign - 2>&1 &&\n> > +\t\ttest_set_prereq GPGSM  \n> \n> And when any of the above fails, we refrain from setting GPGSM\n> prereq.  Otherwise we are prepared to perform tests with gpgsm\n> and get the prereq.\n> \n> > diff --git a/t/t4202-log.sh b/t/t4202-log.sh\n> > index 25b1f8cc7..f57781e39 100755\n> > --- a/t/t4202-log.sh\n> > +++ b/t/t4202-log.sh\n> > @@ -1556,12 +1556,28 @@ test_expect_success GPG 'setup signed\n> > branch' ' git commit -S -m signed_commit\n> >  '\n> >  \n> > +test_expect_success GPGSM 'setup signed branch x509' '\n> > +\ttest_when_finished \"git reset --hard && git checkout\n> > master\" &&\n> > +\tgit checkout -b signed-x509 master &&\n> > +\techo foo >foo &&\n> > +\tgit add foo &&\n> > +\ttest_config gpg.format x509 &&\n> > +\ttest_config user.signingkey $GIT_COMMITTER_EMAIL &&\n> > +\tgit commit -S -m signed_commit\n> > +'  \n> \n> OK.\n> \n> > +test_expect_success GPGSM 'log --graph --show-signature x509' '\n> > +\tgit log --graph --show-signature -n1 signed-x509 >actual &&\n> > +\tgrep \"^| gpgsm: Signature made\" actual &&\n> > +\tgrep \"^| gpgsm: Good signature\" actual\n> > +'  \n> \n> OK.\n> \n> > @@ -1581,6 +1597,29 @@ test_expect_success GPG 'log --graph\n> > --show-signature for merged tag' ' grep \"^| | gpg: Good signature\"\n> > actual '\n> >  \n> > +test_expect_success GPGSM 'log --graph --show-signature for merged\n> > tag x509' '\n> > +\ttest_when_finished \"git reset --hard && git checkout\n> > master\" &&\n> > +\ttest_config gpg.format x509 &&\n> > +\ttest_config user.signingkey $GIT_COMMITTER_EMAIL &&\n> > +\tgit checkout -b plain-x509 master &&\n> > +\techo aaa >bar &&\n> > +\tgit add bar &&\n> > +\tgit commit -m bar_commit &&\n> > +\tgit checkout -b tagged-x509 master &&\n> > +\techo bbb >baz &&\n> > +\tgit add baz &&\n> > +\tgit commit -m baz_commit &&\n> > +\tgit tag -s -m signed_tag_msg signed_tag_x509 &&\n> > +\tgit checkout plain-x509 &&\n> > +\tgit merge --no-ff -m msg signed_tag_x509 &&\n> > +\tgit log --graph --show-signature -n1 plain-x509 >actual &&\n> > +\tgrep \"^|\\\\\\  merged tag\" actual &&\n> > +\tgrep \"^| | gpgsm: Signature made\" actual &&\n> > +\tgrep \"^| | gpgsm: Good signature\" actual &&\n> > +\tgit config --unset gpg.format &&\n> > +\tgit config --unset user.signingkey  \n> \n> You are using test_config early enough in this test; doesn't that\n> take care of the last two steps for you, even when an earlier step\n> failed?  If that is the case, then remove the last two line (and &&\n> at the end of the line before).\n\nRight, dropped those two lines and &&\n\n> > diff --git a/t/t5534-push-signed.sh b/t/t5534-push-signed.sh\n> > index 1cea758f7..a3a12bd05 100755\n> > --- a/t/t5534-push-signed.sh\n> > +++ b/t/t5534-push-signed.sh\n> > @@ -218,4 +218,56 @@ test_expect_success GPG 'fail without key and\n> > heed user.signingkey' ' test_cmp expect dst/push-cert-status\n> >  '\n> >  \n> > +test_expect_success GPGSM 'fail without key and heed\n> > user.signingkey x509' '\n> > +\ttest_config gpg.format x509 &&\n> > +\tenv | grep GIT > envfile &&  \n> \n> The \"envfile\" is unused, no?  Remove this line.\n\nThanks, debugging leftovers.\n\n> > +\tprepare_dst &&\n> > +\tmkdir -p dst/.git/hooks &&\n> > +\tgit -C dst config receive.certnonceseed sekrit &&\n> > +\twrite_script dst/.git/hooks/post-receive <<-\\EOF &&\n> > +\t# discard the update list\n> > +\tcat >/dev/null\n> > +\t# record the push certificate\n> > +\tif test -n \"${GIT_PUSH_CERT-}\"\n> > +\tthen\n> > +\t\tgit cat-file blob $GIT_PUSH_CERT >../push-cert\n> > +\tfi &&\n> > +\n> > +\tcat >../push-cert-status <<E_O_F\n> > +\tSIGNER=${GIT_PUSH_CERT_SIGNER-nobody}\n> > +\tKEY=${GIT_PUSH_CERT_KEY-nokey}\n> > +\tSTATUS=${GIT_PUSH_CERT_STATUS-nostatus}\n> > +\tNONCE_STATUS=${GIT_PUSH_CERT_NONCE_STATUS-nononcestatus}\n> > +\tNONCE=${GIT_PUSH_CERT_NONCE-nononce}\n> > +\tE_O_F\n> > +\n> > +\tEOF  \n> \n> OK, so up to this are what is done by post-receive, including the\n> overwriting of ../push-cert (which is one level above the receiving\n> repository's .git/, i.e. dst/push-cert) and ../push-cert-status.\n> \n> > +\tunset GIT_COMMITTER_EMAIL &&\n> > +\tgit config user.email hasnokey@nowhere.com &&\n> > +\tgit config user.signingkey \"\" &&\n> > +\ttest_must_fail git push --signed dst noop ff +noff &&  \n> \n> This is OK for a test that is known to be always at the end, but\n> also forbids others to further update this script to add more tests\n> at the end, as the standard setting of environment is blown away\n> (the config is probably OK, but test_config to arrange them to be\n> cleaned up would have been nicer), which is not very nice.  I think\n> it should be easy to fix it when it becomes necessary, but at the\n> same time if it is easy to fix, then probably we shouldn't introduce\n> a breakage in the first place, so I am on the fence.\n\nSwitched to test_config, this is all coming from copying the previous\ntests, which i left as is.\n\n> > +\tgit config user.signingkey committer@example.com &&\n> > +\tgit push --signed dst noop ff +noff &&  \n> \n> So,... this is run without resetting user.email and demonstrates\n> that signingkey is the only thing that matters, which makes sense.\n> \n> > +\t(\n> > +\t\tcat <<-\\EOF &&\n> > +\t\tSIGNER=/CN=C O Mitter/O=Example/SN=C O/GN=Mitter\n> > +\t\tKEY=\n> > +\t\tSTATUS=G\n> > +\t\tNONCE_STATUS=OK\n> > +\t\tEOF\n> > +\t\tsed -n -e \"s/^nonce /NONCE=/p\" -e \"/^$/q\"\n> > dst/push-cert\n> > +\t) >expect.in &&\n> > +\tkey=$(cat \"${GNUPGHOME}/trustlist.txt\" | cut -d\" \" -f1 |\n> > tr -d \":\") &&\n> > +\tsed -e \"s/^KEY=/KEY=${key}/\" expect.in > expect &&  \n> \n> s/> expect/>expect/;  \n\nDone.\n\n> > +\tnoop=$(git rev-parse noop) &&\n> > +\tff=$(git rev-parse ff) &&\n> > +\tnoff=$(git rev-parse noff) &&\n> > +\tgrep \"$noop $ff refs/heads/ff\" dst/push-cert &&\n> > +\tgrep \"$noop $noff refs/heads/noff\" dst/push-cert &&\n> > +\ttest_cmp expect dst/push-cert-status\n> > +'\n> > +\n> > +\n> >  test_done\n> > diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh\n> > index d7b319e91..2147938aa 100755\n> > --- a/t/t7004-tag.sh\n> > +++ b/t/t7004-tag.sh\n> > @@ -1354,6 +1354,19 @@ test_expect_success GPG \\\n> >  \t'test_config gpg.program echo &&\n> >  \t test_must_fail git tag -s -m tail tag-gpg-failure'\n> >  \n> > +# try to sign with bad user.signingkey\n> > +test_expect_success GPGSM \\\n> > +\t'git tag -s fails if gpgsm is misconfigured (bad key)' \\\n> > +\t'test_config user.signingkey BobTheMouse &&\n> > +\t test_config gpg.format x509 &&\n> > +\t test_must_fail git tag -s -m tail tag-gpg-failure'\n> > +\n> > +# try to produce invalid signature\n> > +test_expect_success GPGSM \\\n> > +\t'git tag -s fails if gpgsm is misconfigured (bad signature\n> > format)' \\\n> > +\t'test_config gpg.x509.program echo &&\n> > +\t test_config gpg.format x509 &&\n> > +\t test_must_fail git tag -s -m tail tag-gpg-failure'  \n> \n> I can see that it is a gpgsm parallel of the earlier test we can see\n> in the precontext of this hunk done for gpg, but how does the last\n> one (and the original this one was modeled after) fail?\n> \n> We say \"echo\" is the program that signs for the chosen format, \"tag\n> -s\" tries to run \"echo\" instead of \"gpgsm\" with \"--status-fd=2\n> -bsau\" or whatever args we usually give, and...?\n> \n> I would guess you would either get \"I don't know what you wanted me\n> to do with --status-fd=2 option, I am erroring out\" from \"echo\", or\n> the \"echo\" command exiting without consuming any input, causing the\n> feeder in \"tag -s\" to get SIGPIPE (or write(2) error), but the latter\n> happens only when the payload to be signed is large enough.  On a\n> platform whose \"echo\" pays no attention to unknown option, \"echo\"\n> itself may not even error out.  And then we try to read from \"echo\"\n> and we do not get anything (which is expected).  \n> \n> And then who in \"git tag -s\" notice the breakage?\n> \n> \t... goes and looks at gpg-interface.c::sign_buffer() ...\n> \n> Ah, we check the status-fd output for \"[GnuPG:] SIG_CREATED\", which\n> would never happen if we are talking to \"echo\".  OK, that is how\n> this thing is expected to fail.\n> \n> What I have been getting at is if this is really trying to trigger\n> the \"(bad signature format)\" breakage.  The test uses a wrong\n> program to simulate the case where a configured gpg/gpgsm failed to\n> report \"SIG_CREATED\".  \"bad signature format\" does not sound exactly \n> like that, but you inherited the badness from the original, so let's\n> leave it as is.\n\nAll valid points and yes this is coming from copying the other test.\nLeaving as is.\n \n> Thanks.  Modulo a few nits I pointed out above, buried in all the\n> other good bits, this looks reasonable to me.\n\nCool, Thanks.\n\nHenning \n\n"},{"id":"352913","messageId":"xmqqbmb4lbhh.fsf@gitster-ct.c.googlers.com","threadId":"48897","inReplyTo":"20180718123617.55acfd3b@md1pvb1c.ad001.siemens.net","subject":"Re: [PATCH v4 7/7] gpg-interface t: extend the existing GPG tests with GPGSM","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2018-07-18T17:06:34Z","receivedAt":"2018-07-18T17:06:39Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Henning Schild <henning.schild@siemens.com> writes:\n\n>> > +\tunset GIT_COMMITTER_EMAIL &&\n>> > +\tgit config user.email hasnokey@nowhere.com &&\n>> > +\tgit config user.signingkey \"\" &&\n>> > +\ttest_must_fail git push --signed dst noop ff +noff &&  \n>> \n>> This is OK for a test that is known to be always at the end, but\n>> also forbids others to further update this script to add more tests\n>> at the end, as the standard setting of environment is blown away\n>> (the config is probably OK, but test_config to arrange them to be\n>> cleaned up would have been nicer), which is not very nice.  I think\n>> it should be easy to fix it when it becomes necessary, but at the\n>> same time if it is easy to fix, then probably we shouldn't introduce\n>> a breakage in the first place, so I am on the fence.\n>\n> Switched to test_config, this is all coming from copying the previous\n> tests, which i left as is.\n\nI was specifically talking about the unsetting of GIT_COMMITTER_EMAIL,\nnot the configuration variables.\n\nAn easy way to try one step without the environment without\naffecting later tests would be to run the above in a subshell,\nperhaps like\n\n\ttest_config user.email ... &&\n\ttest_config user.signingkey \"\" &&\n\t(\n\t\tsafe_unset GIT_COMMITTER_EMAIL &&\n\t\ttest_must_fail git push --signed ...\n\t) &&\n\n"},{"id":"353022","messageId":"20180719121409.6143-1-henning.schild@siemens.com","threadId":"48897","inReplyTo":"xmqqbmb4lbhh.fsf@gitster-ct.c.googlers.com","subject":"[PATCH] t/t5534: do not unset GIT_COMMITTER_EMAIL for other tests","fromName":"Henning Schild","fromEmail":"henning.schild@siemens.com","sentAt":"2018-07-19T12:14:09Z","receivedAt":"2018-07-19T12:14:44Z","isPatch":true,"sender":{"key":"henning.schild@siemens.com","avatar":"https://avatars.githubusercontent.com/u/7237877?v=4"},"body":"Unsetting the varibale for good can have unwanted effects for new\ntests added in the future It also meant we needed to hardcode the\nvalue for \"user.signingkey\".\nMove the unset into a subshell, get rid of the hardcoded\n\"committer@example.com\", and switch the GPG variant to using test_config\njust like GPGSM.\n\nSigned-off-by: Henning Schild <henning.schild@siemens.com>\n---\n t/t5534-push-signed.sh | 19 ++++++++++++-------\n 1 file changed, 12 insertions(+), 7 deletions(-)\n\ndiff --git a/t/t5534-push-signed.sh b/t/t5534-push-signed.sh\nindex 0cb88aa6f..f6d674156 100755\n--- a/t/t5534-push-signed.sh\n+++ b/t/t5534-push-signed.sh\n@@ -194,10 +194,12 @@ test_expect_success GPG 'fail without key and heed user.signingkey' '\n \n \tEOF\n \n-\tunset GIT_COMMITTER_EMAIL &&\n-\tgit config user.email hasnokey@nowhere.com &&\n-\ttest_must_fail git push --signed dst noop ff +noff &&\n-\tgit config user.signingkey committer@example.com &&\n+\ttest_config user.email hasnokey@nowhere.com &&\n+\t(\n+\t\tunset GIT_COMMITTER_EMAIL &&\n+\t\ttest_must_fail git push --signed dst noop ff +noff\n+\t) &&\n+\ttest_config user.signingkey $GIT_COMMITTER_EMAIL &&\n \tgit push --signed dst noop ff +noff &&\n \n \t(\n@@ -241,11 +243,14 @@ test_expect_success GPGSM 'fail without key and heed user.signingkey x509' '\n \tE_O_F\n \n \tEOF\n-\tunset GIT_COMMITTER_EMAIL &&\n+\n \ttest_config user.email hasnokey@nowhere.com &&\n \ttest_config user.signingkey \"\" &&\n-\ttest_must_fail git push --signed dst noop ff +noff &&\n-\ttest_config user.signingkey committer@example.com &&\n+\t(\n+\t\tunset GIT_COMMITTER_EMAIL &&\n+\t\ttest_must_fail git push --signed dst noop ff +noff\n+\t) &&\n+\ttest_config user.signingkey $GIT_COMMITTER_EMAIL &&\n \tgit push --signed dst noop ff +noff &&\n \n \t(\n-- \n2.16.4\n\n"},{"id":"353023","messageId":"20180719141545.48358a26@md1pvb1c.ad001.siemens.net","threadId":"48897","inReplyTo":"20180719121409.6143-1-henning.schild@siemens.com","subject":"Re: [PATCH] t/t5534: do not unset GIT_COMMITTER_EMAIL for other tests","fromName":"Henning Schild","fromEmail":"henning.schild@siemens.com","sentAt":"2018-07-19T12:15:45Z","receivedAt":"2018-07-19T12:16:05Z","isPatch":true,"sender":{"key":"henning.schild@siemens.com","avatar":"https://avatars.githubusercontent.com/u/7237877?v=4"},"body":"Looking at \"what is cooking\" i assume i should not add/fold this to/in\nthe serien anymore. So it comes as a separate patch on top.\n\nHenning\n\nAm Thu, 19 Jul 2018 14:14:09 +0200\nschrieb Henning Schild <henning.schild@siemens.com>:\n\n> Unsetting the varibale for good can have unwanted effects for new\n> tests added in the future It also meant we needed to hardcode the\n> value for \"user.signingkey\".\n> Move the unset into a subshell, get rid of the hardcoded\n> \"committer@example.com\", and switch the GPG variant to using\n> test_config just like GPGSM.\n> \n> Signed-off-by: Henning Schild <henning.schild@siemens.com>\n> ---\n>  t/t5534-push-signed.sh | 19 ++++++++++++-------\n>  1 file changed, 12 insertions(+), 7 deletions(-)\n> \n> diff --git a/t/t5534-push-signed.sh b/t/t5534-push-signed.sh\n> index 0cb88aa6f..f6d674156 100755\n> --- a/t/t5534-push-signed.sh\n> +++ b/t/t5534-push-signed.sh\n> @@ -194,10 +194,12 @@ test_expect_success GPG 'fail without key and\n> heed user.signingkey' ' \n>  \tEOF\n>  \n> -\tunset GIT_COMMITTER_EMAIL &&\n> -\tgit config user.email hasnokey@nowhere.com &&\n> -\ttest_must_fail git push --signed dst noop ff +noff &&\n> -\tgit config user.signingkey committer@example.com &&\n> +\ttest_config user.email hasnokey@nowhere.com &&\n> +\t(\n> +\t\tunset GIT_COMMITTER_EMAIL &&\n> +\t\ttest_must_fail git push --signed dst noop ff +noff\n> +\t) &&\n> +\ttest_config user.signingkey $GIT_COMMITTER_EMAIL &&\n>  \tgit push --signed dst noop ff +noff &&\n>  \n>  \t(\n> @@ -241,11 +243,14 @@ test_expect_success GPGSM 'fail without key and\n> heed user.signingkey x509' ' E_O_F\n>  \n>  \tEOF\n> -\tunset GIT_COMMITTER_EMAIL &&\n> +\n>  \ttest_config user.email hasnokey@nowhere.com &&\n>  \ttest_config user.signingkey \"\" &&\n> -\ttest_must_fail git push --signed dst noop ff +noff &&\n> -\ttest_config user.signingkey committer@example.com &&\n> +\t(\n> +\t\tunset GIT_COMMITTER_EMAIL &&\n> +\t\ttest_must_fail git push --signed dst noop ff +noff\n> +\t) &&\n> +\ttest_config user.signingkey $GIT_COMMITTER_EMAIL &&\n>  \tgit push --signed dst noop ff +noff &&\n>  \n>  \t(\n\n"},{"id":"353028","messageId":"20180719151028.GA35774@syl.attlocal.net","threadId":"48897","inReplyTo":"20180719121409.6143-1-henning.schild@siemens.com","subject":"Re: [PATCH] t/t5534: do not unset GIT_COMMITTER_EMAIL for other tests","fromName":"Taylor Blau","fromEmail":"me@ttaylorr.com","sentAt":"2018-07-19T15:10:28Z","receivedAt":"2018-07-19T15:10:34Z","isPatch":true,"sender":{"key":"me@ttaylorr.com","avatar":"https://avatars.githubusercontent.com/u/301000140?v=4"},"body":"On Thu, Jul 19, 2018 at 02:14:09PM +0200, Henning Schild wrote:\n> Unsetting the varibale for good can have unwanted effects for new\n\ns/varibale/variable\n\n> tests added in the future It also meant we needed to hardcode the\n\ns/future/&.\n\n> value for \"user.signingkey\".\n> Move the unset into a subshell, get rid of the hardcoded\n> \"committer@example.com\", and switch the GPG variant to using test_config\n> just like GPGSM.\n\nOK, sounds good.\n\n> Signed-off-by: Henning Schild <henning.schild@siemens.com>\n> ---\n>  t/t5534-push-signed.sh | 19 ++++++++++++-------\n>  1 file changed, 12 insertions(+), 7 deletions(-)\n>\n> diff --git a/t/t5534-push-signed.sh b/t/t5534-push-signed.sh\n> index 0cb88aa6f..f6d674156 100755\n> --- a/t/t5534-push-signed.sh\n> +++ b/t/t5534-push-signed.sh\n> @@ -194,10 +194,12 @@ test_expect_success GPG 'fail without key and heed user.signingkey' '\n>\n>  \tEOF\n>\n> -\tunset GIT_COMMITTER_EMAIL &&\n> -\tgit config user.email hasnokey@nowhere.com &&\n> -\ttest_must_fail git push --signed dst noop ff +noff &&\n> -\tgit config user.signingkey committer@example.com &&\n> +\ttest_config user.email hasnokey@nowhere.com &&\n> +\t(\n> +\t\tunset GIT_COMMITTER_EMAIL &&\n> +\t\ttest_must_fail git push --signed dst noop ff +noff\n> +\t) &&\n> +\ttest_config user.signingkey $GIT_COMMITTER_EMAIL &&\n>  \tgit push --signed dst noop ff +noff &&\n\nI think replacing the 'git config' invocations with their 'test_config'\nequivalents in its own patch would be easier to grok, but I don't think\nthat splitting the change out is worth a re-roll on its own.\n\n>  \t(\n> @@ -241,11 +243,14 @@ test_expect_success GPGSM 'fail without key and heed user.signingkey x509' '\n>  \tE_O_F\n>\n>  \tEOF\n> -\tunset GIT_COMMITTER_EMAIL &&\n> +\n\nNit; remove this newline.\n\n>  \ttest_config user.email hasnokey@nowhere.com &&\n>  \ttest_config user.signingkey \"\" &&\n> -\ttest_must_fail git push --signed dst noop ff +noff &&\n> -\ttest_config user.signingkey committer@example.com &&\n> +\t(\n> +\t\tunset GIT_COMMITTER_EMAIL &&\n> +\t\ttest_must_fail git push --signed dst noop ff +noff\n> +\t) &&\n> +\ttest_config user.signingkey $GIT_COMMITTER_EMAIL &&\n>  \tgit push --signed dst noop ff +noff &&\n\nLooks good.\n\n>  \t(\n> --\n> 2.16.4\n\nThanks,\nTaylor\n"},{"id":"353097","messageId":"xmqqzhymdfo3.fsf@gitster-ct.c.googlers.com","threadId":"48897","inReplyTo":"20180719141545.48358a26@md1pvb1c.ad001.siemens.net","subject":"Re: [PATCH] t/t5534: do not unset GIT_COMMITTER_EMAIL for other tests","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2018-07-19T22:27:56Z","receivedAt":"2018-07-19T22:28:00Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Henning Schild <henning.schild@siemens.com> writes:\n\n> Looking at \"what is cooking\" i assume i should not add/fold this to/in\n> the serien anymore. So it comes as a separate patch on top.\n\nThanks.  I only said:\n\n     I think this round is mostly ready, except for a minor nit in the\n     last step.  I do not mind merging this to 'next' and leave fixing\n     of the test to a later clean-up.\n\nmeaing that I _do not mind_ merging the slightly broken one to\n'next' and fixing it with a follow-up (i.e. this patch), but fixing\nwith a replacement patch so that we pretend we never made a mistake\nthat needs fixing from the beginning is of course preferrable ;-)\n\nLet's squash this patch into the last one in the series.\n"},{"id":"353116","messageId":"20180720082807.2917-1-henning.schild@siemens.com","threadId":"48897","inReplyTo":"20180718093112.29783-1-henning.schild@siemens.com","subject":"[PATCH v6 7/7] gpg-interface t: extend the existing GPG tests with GPGSM","fromName":"Henning Schild","fromEmail":"henning.schild@siemens.com","sentAt":"2018-07-20T08:28:07Z","receivedAt":"2018-07-20T08:28:35Z","isPatch":true,"sender":{"key":"henning.schild@siemens.com","avatar":"https://avatars.githubusercontent.com/u/7237877?v=4"},"body":"Add test cases to cover the new X509/gpgsm support. Most of them\nresemble existing ones. They just switch the format to x509 and set the\nsigningkey when creating signatures. Validation of signatures does not\nneed any configuration of git, it does need gpgsm to be configured to\ntrust the key(-chain).\nSeveral of the testcases build on top of existing gpg testcases.\nThe commit ships a self-signed key for committer@example.com and\nconfigures gpgsm to trust it.\n\nSigned-off-by: Henning Schild <henning.schild@siemens.com>\n---\n t/lib-gpg.sh               |  28 +++++++++++++++++++-\n t/lib-gpg/gpgsm-gen-key.in |   8 ++++++\n t/lib-gpg/gpgsm_cert.p12   | Bin 0 -> 2652 bytes\n t/t4202-log.sh             |  37 ++++++++++++++++++++++++++\n t/t5534-push-signed.sh     |  63 ++++++++++++++++++++++++++++++++++++++++++---\n t/t7004-tag.sh             |  13 ++++++++++\n t/t7030-verify-tag.sh      |  34 ++++++++++++++++++++++++\n 7 files changed, 178 insertions(+), 5 deletions(-)\n create mode 100644 t/lib-gpg/gpgsm-gen-key.in\n create mode 100644 t/lib-gpg/gpgsm_cert.p12\n\ndiff --git a/t/lib-gpg.sh b/t/lib-gpg.sh\nindex a5d3b2cba..3fe02876c 100755\n--- a/t/lib-gpg.sh\n+++ b/t/lib-gpg.sh\n@@ -38,7 +38,33 @@ then\n \t\t\t\"$TEST_DIRECTORY\"/lib-gpg/ownertrust &&\n \t\tgpg --homedir \"${GNUPGHOME}\" </dev/null >/dev/null 2>&1 \\\n \t\t\t--sign -u committer@example.com &&\n-\t\ttest_set_prereq GPG\n+\t\ttest_set_prereq GPG &&\n+\t\t# Available key info:\n+\t\t# * see t/lib-gpg/gpgsm-gen-key.in\n+\t\t# To generate new certificate:\n+\t\t#  * no passphrase\n+\t\t#\tgpgsm --homedir /tmp/gpghome/ \\\n+\t\t#\t\t-o /tmp/gpgsm.crt.user \\\n+\t\t#\t\t--generate-key \\\n+\t\t#\t\t--batch t/lib-gpg/gpgsm-gen-key.in\n+\t\t# To import certificate:\n+\t\t#\tgpgsm --homedir /tmp/gpghome/ \\\n+\t\t#\t\t--import /tmp/gpgsm.crt.user\n+\t\t# To export into a .p12 we can later import:\n+\t\t#\tgpgsm --homedir /tmp/gpghome/ \\\n+\t\t#\t\t-o t/lib-gpg/gpgsm_cert.p12 \\\n+\t\t#\t\t--export-secret-key-p12 \"committer@example.com\"\n+\t\techo | gpgsm --homedir \"${GNUPGHOME}\" 2>/dev/null \\\n+\t\t\t--passphrase-fd 0 --pinentry-mode loopback \\\n+\t\t\t--import \"$TEST_DIRECTORY\"/lib-gpg/gpgsm_cert.p12 &&\n+\t\tgpgsm --homedir \"${GNUPGHOME}\" 2>/dev/null -K \\\n+\t\t\t| grep fingerprint: | cut -d\" \" -f4 | tr -d '\\n' > \\\n+\t\t\t${GNUPGHOME}/trustlist.txt &&\n+\t\techo \" S relax\" >> ${GNUPGHOME}/trustlist.txt &&\n+\t\t(gpgconf --kill gpg-agent >/dev/null 2>&1 || : ) &&\n+\t\techo hello | gpgsm --homedir \"${GNUPGHOME}\" >/dev/null \\\n+\t\t\t-u committer@example.com -o /dev/null --sign - 2>&1 &&\n+\t\ttest_set_prereq GPGSM\n \t\t;;\n \tesac\n fi\ndiff --git a/t/lib-gpg/gpgsm-gen-key.in b/t/lib-gpg/gpgsm-gen-key.in\nnew file mode 100644\nindex 000000000..a7fd87c06\n--- /dev/null\n+++ b/t/lib-gpg/gpgsm-gen-key.in\n@@ -0,0 +1,8 @@\n+Key-Type: RSA\n+Key-Length: 2048\n+Key-Usage: sign\n+Serial: random\n+Name-DN: CN=C O Mitter, O=Example, SN=C O, GN=Mitter\n+Name-Email: committer@example.com\n+Not-Before: 1970-01-01 00:00:00\n+Not-After: 3000-01-01 00:00:00\ndiff --git a/t/lib-gpg/gpgsm_cert.p12 b/t/lib-gpg/gpgsm_cert.p12\nnew file mode 100644\nindex 0000000000000000000000000000000000000000..94ffad0d31a3b6c4e849b29d960762e485ba7ea8\nGIT binary patch\nliteral 2652\n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\n\nliteral 0\nHcmV?d00001\n\ndiff --git a/t/t4202-log.sh b/t/t4202-log.sh\nindex 25b1f8cc7..05d3707e3 100755\n--- a/t/t4202-log.sh\n+++ b/t/t4202-log.sh\n@@ -1556,12 +1556,28 @@ test_expect_success GPG 'setup signed branch' '\n \tgit commit -S -m signed_commit\n '\n \n+test_expect_success GPGSM 'setup signed branch x509' '\n+\ttest_when_finished \"git reset --hard && git checkout master\" &&\n+\tgit checkout -b signed-x509 master &&\n+\techo foo >foo &&\n+\tgit add foo &&\n+\ttest_config gpg.format x509 &&\n+\ttest_config user.signingkey $GIT_COMMITTER_EMAIL &&\n+\tgit commit -S -m signed_commit\n+'\n+\n test_expect_success GPG 'log --graph --show-signature' '\n \tgit log --graph --show-signature -n1 signed >actual &&\n \tgrep \"^| gpg: Signature made\" actual &&\n \tgrep \"^| gpg: Good signature\" actual\n '\n \n+test_expect_success GPGSM 'log --graph --show-signature x509' '\n+\tgit log --graph --show-signature -n1 signed-x509 >actual &&\n+\tgrep \"^| gpgsm: Signature made\" actual &&\n+\tgrep \"^| gpgsm: Good signature\" actual\n+'\n+\n test_expect_success GPG 'log --graph --show-signature for merged tag' '\n \ttest_when_finished \"git reset --hard && git checkout master\" &&\n \tgit checkout -b plain master &&\n@@ -1581,6 +1597,27 @@ test_expect_success GPG 'log --graph --show-signature for merged tag' '\n \tgrep \"^| | gpg: Good signature\" actual\n '\n \n+test_expect_success GPGSM 'log --graph --show-signature for merged tag x509' '\n+\ttest_when_finished \"git reset --hard && git checkout master\" &&\n+\ttest_config gpg.format x509 &&\n+\ttest_config user.signingkey $GIT_COMMITTER_EMAIL &&\n+\tgit checkout -b plain-x509 master &&\n+\techo aaa >bar &&\n+\tgit add bar &&\n+\tgit commit -m bar_commit &&\n+\tgit checkout -b tagged-x509 master &&\n+\techo bbb >baz &&\n+\tgit add baz &&\n+\tgit commit -m baz_commit &&\n+\tgit tag -s -m signed_tag_msg signed_tag_x509 &&\n+\tgit checkout plain-x509 &&\n+\tgit merge --no-ff -m msg signed_tag_x509 &&\n+\tgit log --graph --show-signature -n1 plain-x509 >actual &&\n+\tgrep \"^|\\\\\\  merged tag\" actual &&\n+\tgrep \"^| | gpgsm: Signature made\" actual &&\n+\tgrep \"^| | gpgsm: Good signature\" actual\n+'\n+\n test_expect_success GPG '--no-show-signature overrides --show-signature' '\n \tgit log -1 --show-signature --no-show-signature signed >actual &&\n \t! grep \"^gpg:\" actual\ndiff --git a/t/t5534-push-signed.sh b/t/t5534-push-signed.sh\nindex 1cea758f7..8cc6789e9 100755\n--- a/t/t5534-push-signed.sh\n+++ b/t/t5534-push-signed.sh\n@@ -194,10 +194,12 @@ test_expect_success GPG 'fail without key and heed user.signingkey' '\n \n \tEOF\n \n-\tunset GIT_COMMITTER_EMAIL &&\n-\tgit config user.email hasnokey@nowhere.com &&\n-\ttest_must_fail git push --signed dst noop ff +noff &&\n-\tgit config user.signingkey committer@example.com &&\n+\ttest_config user.email hasnokey@nowhere.com &&\n+\t(\n+\t\tunset GIT_COMMITTER_EMAIL &&\n+\t\ttest_must_fail git push --signed dst noop ff +noff\n+\t) &&\n+\ttest_config user.signingkey $GIT_COMMITTER_EMAIL &&\n \tgit push --signed dst noop ff +noff &&\n \n \t(\n@@ -218,4 +220,57 @@ test_expect_success GPG 'fail without key and heed user.signingkey' '\n \ttest_cmp expect dst/push-cert-status\n '\n \n+test_expect_success GPGSM 'fail without key and heed user.signingkey x509' '\n+\ttest_config gpg.format x509 &&\n+\tprepare_dst &&\n+\tmkdir -p dst/.git/hooks &&\n+\tgit -C dst config receive.certnonceseed sekrit &&\n+\twrite_script dst/.git/hooks/post-receive <<-\\EOF &&\n+\t# discard the update list\n+\tcat >/dev/null\n+\t# record the push certificate\n+\tif test -n \"${GIT_PUSH_CERT-}\"\n+\tthen\n+\t\tgit cat-file blob $GIT_PUSH_CERT >../push-cert\n+\tfi &&\n+\n+\tcat >../push-cert-status <<E_O_F\n+\tSIGNER=${GIT_PUSH_CERT_SIGNER-nobody}\n+\tKEY=${GIT_PUSH_CERT_KEY-nokey}\n+\tSTATUS=${GIT_PUSH_CERT_STATUS-nostatus}\n+\tNONCE_STATUS=${GIT_PUSH_CERT_NONCE_STATUS-nononcestatus}\n+\tNONCE=${GIT_PUSH_CERT_NONCE-nononce}\n+\tE_O_F\n+\n+\tEOF\n+\n+\ttest_config user.email hasnokey@nowhere.com &&\n+\ttest_config user.signingkey \"\" &&\n+\t(\n+\t\tunset GIT_COMMITTER_EMAIL &&\n+\t\ttest_must_fail git push --signed dst noop ff +noff\n+\t) &&\n+\ttest_config user.signingkey $GIT_COMMITTER_EMAIL &&\n+\tgit push --signed dst noop ff +noff &&\n+\n+\t(\n+\t\tcat <<-\\EOF &&\n+\t\tSIGNER=/CN=C O Mitter/O=Example/SN=C O/GN=Mitter\n+\t\tKEY=\n+\t\tSTATUS=G\n+\t\tNONCE_STATUS=OK\n+\t\tEOF\n+\t\tsed -n -e \"s/^nonce /NONCE=/p\" -e \"/^$/q\" dst/push-cert\n+\t) >expect.in &&\n+\tkey=$(cat \"${GNUPGHOME}/trustlist.txt\" | cut -d\" \" -f1 | tr -d \":\") &&\n+\tsed -e \"s/^KEY=/KEY=${key}/\" expect.in >expect &&\n+\n+\tnoop=$(git rev-parse noop) &&\n+\tff=$(git rev-parse ff) &&\n+\tnoff=$(git rev-parse noff) &&\n+\tgrep \"$noop $ff refs/heads/ff\" dst/push-cert &&\n+\tgrep \"$noop $noff refs/heads/noff\" dst/push-cert &&\n+\ttest_cmp expect dst/push-cert-status\n+'\n+\n test_done\ndiff --git a/t/t7004-tag.sh b/t/t7004-tag.sh\nindex d7b319e91..2147938aa 100755\n--- a/t/t7004-tag.sh\n+++ b/t/t7004-tag.sh\n@@ -1354,6 +1354,19 @@ test_expect_success GPG \\\n \t'test_config gpg.program echo &&\n \t test_must_fail git tag -s -m tail tag-gpg-failure'\n \n+# try to sign with bad user.signingkey\n+test_expect_success GPGSM \\\n+\t'git tag -s fails if gpgsm is misconfigured (bad key)' \\\n+\t'test_config user.signingkey BobTheMouse &&\n+\t test_config gpg.format x509 &&\n+\t test_must_fail git tag -s -m tail tag-gpg-failure'\n+\n+# try to produce invalid signature\n+test_expect_success GPGSM \\\n+\t'git tag -s fails if gpgsm is misconfigured (bad signature format)' \\\n+\t'test_config gpg.x509.program echo &&\n+\t test_config gpg.format x509 &&\n+\t test_must_fail git tag -s -m tail tag-gpg-failure'\n \n # try to verify without gpg:\n \ndiff --git a/t/t7030-verify-tag.sh b/t/t7030-verify-tag.sh\nindex 291a1e2b0..99f35a5bb 100755\n--- a/t/t7030-verify-tag.sh\n+++ b/t/t7030-verify-tag.sh\n@@ -41,6 +41,13 @@ test_expect_success GPG 'create signed tags' '\n \tgit tag -uB7227189 -m eighth eighth-signed-alt\n '\n \n+test_expect_success GPGSM 'create signed tags x509 ' '\n+\ttest_config gpg.format x509 &&\n+\ttest_config user.signingkey $GIT_COMMITTER_EMAIL &&\n+\techo 9 >file && test_tick && git commit -a -m \"nineth gpgsm-signed\" &&\n+\tgit tag -s -m nineth nineth-signed-x509\n+'\n+\n test_expect_success GPG 'verify and show signatures' '\n \t(\n \t\tfor tag in initial second merge fourth-signed sixth-signed seventh-signed\n@@ -72,6 +79,13 @@ test_expect_success GPG 'verify and show signatures' '\n \t)\n '\n \n+test_expect_success GPGSM 'verify and show signatures x509' '\n+\tgit verify-tag nineth-signed-x509 2>actual &&\n+\tgrep \"Good signature from\" actual &&\n+\t! grep \"BAD signature from\" actual &&\n+\techo nineth-signed-x509 OK\n+'\n+\n test_expect_success GPG 'detect fudged signature' '\n \tgit cat-file tag seventh-signed >raw &&\n \tsed -e \"/^tag / s/seventh/7th forged/\" raw >forged1 &&\n@@ -112,6 +126,13 @@ test_expect_success GPG 'verify signatures with --raw' '\n \t)\n '\n \n+test_expect_success GPGSM 'verify signatures with --raw x509' '\n+\tgit verify-tag --raw nineth-signed-x509 2>actual &&\n+\tgrep \"GOODSIG\" actual &&\n+\t! grep \"BADSIG\" actual &&\n+\techo nineth-signed-x509 OK\n+'\n+\n test_expect_success GPG 'verify multiple tags' '\n \ttags=\"fourth-signed sixth-signed seventh-signed\" &&\n \tfor i in $tags\n@@ -125,6 +146,19 @@ test_expect_success GPG 'verify multiple tags' '\n \ttest_cmp expect.stderr actual.stderr\n '\n \n+test_expect_success GPGSM 'verify multiple tags x509' '\n+\ttags=\"seventh-signed nineth-signed-x509\" &&\n+\tfor i in $tags\n+\tdo\n+\t\tgit verify-tag -v --raw $i || return 1\n+\tdone >expect.stdout 2>expect.stderr.1 &&\n+\tgrep \"^.GNUPG:.\" <expect.stderr.1 >expect.stderr &&\n+\tgit verify-tag -v --raw $tags >actual.stdout 2>actual.stderr.1 &&\n+\tgrep \"^.GNUPG:.\" <actual.stderr.1 >actual.stderr &&\n+\ttest_cmp expect.stdout actual.stdout &&\n+\ttest_cmp expect.stderr actual.stderr\n+'\n+\n test_expect_success GPG 'verifying tag with --format' '\n \tcat >expect <<-\\EOF &&\n \ttagname : fourth-signed\n-- \n2.16.4\n\n"},{"id":"353117","messageId":"20180720102840.37f28d17@md1pvb1c.ad001.siemens.net","threadId":"48897","inReplyTo":"xmqqzhymdfo3.fsf@gitster-ct.c.googlers.com","subject":"Re: [PATCH] t/t5534: do not unset GIT_COMMITTER_EMAIL for other tests","fromName":"Henning Schild","fromEmail":"henning.schild@siemens.com","sentAt":"2018-07-20T08:28:40Z","receivedAt":"2018-07-20T08:28:58Z","isPatch":true,"sender":{"key":"henning.schild@siemens.com","avatar":"https://avatars.githubusercontent.com/u/7237877?v=4"},"body":"Am Thu, 19 Jul 2018 15:27:56 -0700\nschrieb Junio C Hamano <gitster@pobox.com>:\n\n> Henning Schild <henning.schild@siemens.com> writes:\n> \n> > Looking at \"what is cooking\" i assume i should not add/fold this\n> > to/in the serien anymore. So it comes as a separate patch on top.  \n> \n> Thanks.  I only said:\n> \n>      I think this round is mostly ready, except for a minor nit in the\n>      last step.  I do not mind merging this to 'next' and leave fixing\n>      of the test to a later clean-up.\n> \n> meaing that I _do not mind_ merging the slightly broken one to\n> 'next' and fixing it with a follow-up (i.e. this patch), but fixing\n> with a replacement patch so that we pretend we never made a mistake\n> that needs fixing from the beginning is of course preferrable ;-)\n> \n> Let's squash this patch into the last one in the series.\n\nOk, just sent a v6 of 7/7.\n\nHenning\n"},{"id":"353127","messageId":"xmqq6019did2.fsf@gitster-ct.c.googlers.com","threadId":"48897","inReplyTo":"20180720082807.2917-1-henning.schild@siemens.com","subject":"Re: [PATCH v6 7/7] gpg-interface t: extend the existing GPG tests with GPGSM","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2018-07-20T15:42:01Z","receivedAt":"2018-07-20T15:42:05Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Thanks.\n"}]}