66#include "gpg-interface.h"
77#include "sigchain.h"
88#include "tempfile.h"
9+ #include "alias.h"
910
1011static char * configured_signing_key ;
12+ static const char * ssh_default_key_command ;
1113static enum signature_trust_level configured_min_trust_level = TRUST_UNDEFINED ;
1214
1315struct gpg_format {
@@ -21,6 +23,7 @@ struct gpg_format {
2123 size_t signature_size );
2224 int (* sign_buffer )(struct strbuf * buffer , struct strbuf * signature ,
2325 const char * signing_key );
26+ const char * (* get_default_key )(void );
2427};
2528
2629static const char * openpgp_verify_args [] = {
@@ -56,6 +59,8 @@ static int sign_buffer_gpg(struct strbuf *buffer, struct strbuf *signature,
5659static int sign_buffer_ssh (struct strbuf * buffer , struct strbuf * signature ,
5760 const char * signing_key );
5861
62+ static const char * get_default_ssh_signing_key (void );
63+
5964static struct gpg_format gpg_format [] = {
6065 {
6166 .name = "openpgp" ,
@@ -64,6 +69,7 @@ static struct gpg_format gpg_format[] = {
6469 .sigs = openpgp_sigs ,
6570 .verify_signed_buffer = verify_gpg_signed_buffer ,
6671 .sign_buffer = sign_buffer_gpg ,
72+ .get_default_key = NULL ,
6773 },
6874 {
6975 .name = "x509" ,
@@ -72,14 +78,16 @@ static struct gpg_format gpg_format[] = {
7278 .sigs = x509_sigs ,
7379 .verify_signed_buffer = verify_gpg_signed_buffer ,
7480 .sign_buffer = sign_buffer_gpg ,
81+ .get_default_key = NULL ,
7582 },
7683 {
7784 .name = "ssh" ,
7885 .program = "ssh-keygen" ,
7986 .verify_args = ssh_verify_args ,
8087 .sigs = ssh_sigs ,
8188 .verify_signed_buffer = NULL , /* TODO */
82- .sign_buffer = sign_buffer_ssh
89+ .sign_buffer = sign_buffer_ssh ,
90+ .get_default_key = get_default_ssh_signing_key ,
8391 },
8492};
8593
@@ -453,6 +461,12 @@ int git_gpg_config(const char *var, const char *value, void *cb)
453461 return 0 ;
454462 }
455463
464+ if (!strcmp (var , "gpg.ssh.defaultkeycommand" )) {
465+ if (!value )
466+ return config_error_nonbool (var );
467+ return git_config_string (& ssh_default_key_command , var , value );
468+ }
469+
456470 if (!strcmp (var , "gpg.program" ) || !strcmp (var , "gpg.openpgp.program" ))
457471 fmtname = "openpgp" ;
458472
@@ -470,11 +484,63 @@ int git_gpg_config(const char *var, const char *value, void *cb)
470484 return 0 ;
471485}
472486
487+ /* Returns the first public key from an ssh-agent to use for signing */
488+ static const char * get_default_ssh_signing_key (void )
489+ {
490+ struct child_process ssh_default_key = CHILD_PROCESS_INIT ;
491+ int ret = -1 ;
492+ struct strbuf key_stdout = STRBUF_INIT , key_stderr = STRBUF_INIT ;
493+ struct strbuf * * keys ;
494+ char * key_command = NULL ;
495+ const char * * argv ;
496+ int n ;
497+ char * default_key = NULL ;
498+
499+ if (!ssh_default_key_command )
500+ die (_ ("either user.signingkey or gpg.ssh.defaultKeyCommand needs to be configured" ));
501+
502+ key_command = xstrdup (ssh_default_key_command );
503+ n = split_cmdline (key_command , & argv );
504+
505+ if (n < 0 )
506+ die ("malformed build-time gpg.ssh.defaultKeyCommand: %s" ,
507+ split_cmdline_strerror (n ));
508+
509+ strvec_pushv (& ssh_default_key .args , argv );
510+ ret = pipe_command (& ssh_default_key , NULL , 0 , & key_stdout , 0 ,
511+ & key_stderr , 0 );
512+
513+ if (!ret ) {
514+ keys = strbuf_split_max (& key_stdout , '\n' , 2 );
515+ if (keys [0 ] && starts_with (keys [0 ]-> buf , "ssh-" )) {
516+ default_key = strbuf_detach (keys [0 ], NULL );
517+ } else {
518+ warning (_ ("gpg.ssh.defaultKeycommand succeeded but returned no keys: %s %s" ),
519+ key_stderr .buf , key_stdout .buf );
520+ }
521+
522+ strbuf_list_free (keys );
523+ } else {
524+ warning (_ ("gpg.ssh.defaultKeyCommand failed: %s %s" ),
525+ key_stderr .buf , key_stdout .buf );
526+ }
527+
528+ free (key_command );
529+ free (argv );
530+ strbuf_release (& key_stdout );
531+
532+ return default_key ;
533+ }
534+
473535const char * get_signing_key (void )
474536{
475537 if (configured_signing_key )
476538 return configured_signing_key ;
477- return git_committer_info (IDENT_STRICT |IDENT_NO_DATE );
539+ if (use_format -> get_default_key ) {
540+ return use_format -> get_default_key ();
541+ }
542+
543+ return git_committer_info (IDENT_STRICT | IDENT_NO_DATE );
478544}
479545
480546int sign_buffer (struct strbuf * buffer , struct strbuf * signature , const char * signing_key )
0 commit comments