| 459 | } |
| 460 | |
| 461 | static int verify_ssh_signed_buffer(struct signature_check *sigc, |
| 462 | struct gpg_format *fmt, |
| 463 | const char *signature, |
| 464 | size_t signature_size) |
| 465 | { |
| 466 | struct child_process ssh_keygen = CHILD_PROCESS_INIT; |
| 467 | struct tempfile *buffer_file; |
| 468 | int ret = -1; |
| 469 | const char *line; |
| 470 | char *principal; |
| 471 | struct strbuf ssh_principals_out = STRBUF_INIT; |
| 472 | struct strbuf ssh_principals_err = STRBUF_INIT; |
| 473 | struct strbuf ssh_keygen_out = STRBUF_INIT; |
| 474 | struct strbuf ssh_keygen_err = STRBUF_INIT; |
| 475 | struct strbuf verify_time = STRBUF_INIT; |
| 476 | const struct date_mode verify_date_mode = { |
| 477 | .type = DATE_STRFTIME, |
| 478 | .strftime_fmt = "%Y%m%d%H%M%S", |
| 479 | /* SSH signing key validity has no timezone information - Use the local timezone */ |
| 480 | .local = 1, |
| 481 | }; |
| 482 | |
| 483 | if (!ssh_allowed_signers) { |
| 484 | error(_("gpg.ssh.allowedSignersFile needs to be configured and exist for ssh signature verification")); |
| 485 | return -1; |
| 486 | } |
| 487 | |
| 488 | buffer_file = mks_tempfile_t(".git_vtag_tmpXXXXXX"); |
| 489 | if (!buffer_file) |
| 490 | return error_errno(_("could not create temporary file")); |
| 491 | if (write_in_full(buffer_file->fd, signature, signature_size) < 0 || |
| 492 | close_tempfile_gently(buffer_file) < 0) { |
| 493 | error_errno(_("failed writing detached signature to '%s'"), |
| 494 | buffer_file->filename.buf); |
| 495 | delete_tempfile(&buffer_file); |
| 496 | return -1; |
| 497 | } |
| 498 | |
| 499 | if (sigc->payload_timestamp) |
| 500 | strbuf_addf(&verify_time, "-Overify-time=%s", |
| 501 | show_date(sigc->payload_timestamp, 0, verify_date_mode)); |
| 502 | |
| 503 | /* Find the principal from the signers */ |
| 504 | strvec_pushl(&ssh_keygen.args, fmt->program, |
| 505 | "-Y", "find-principals", |
| 506 | "-f", ssh_allowed_signers, |
| 507 | "-s", buffer_file->filename.buf, |
| 508 | verify_time.buf, |
| 509 | NULL); |
| 510 | ret = pipe_command(&ssh_keygen, NULL, 0, &ssh_principals_out, 0, |
| 511 | &ssh_principals_err, 0); |
| 512 | if (ret && strstr(ssh_principals_err.buf, "usage:")) { |
| 513 | error(_("ssh-keygen -Y find-principals/verify is needed for ssh signature verification (available in openssh version 8.2p1+)")); |
| 514 | goto out; |
| 515 | } |
| 516 | if (ret || !ssh_principals_out.len) { |
| 517 | /* |
| 518 | * We did not find a matching principal in the allowedSigners |
nothing calls this directly
no test coverage detected