@@ -24,6 +24,7 @@ struct gpg_format {
24
24
int (* sign_buffer )(struct strbuf * buffer , struct strbuf * signature ,
25
25
const char * signing_key );
26
26
const char * (* get_default_key )(void );
27
+ const char * (* get_key_id )(void );
27
28
};
28
29
29
30
static const char * openpgp_verify_args [] = {
@@ -61,6 +62,8 @@ static int sign_buffer_ssh(struct strbuf *buffer, struct strbuf *signature,
61
62
62
63
static const char * get_default_ssh_signing_key (void );
63
64
65
+ static const char * get_ssh_key_id (void );
66
+
64
67
static struct gpg_format gpg_format [] = {
65
68
{
66
69
.name = "openpgp" ,
@@ -70,6 +73,7 @@ static struct gpg_format gpg_format[] = {
70
73
.verify_signed_buffer = verify_gpg_signed_buffer ,
71
74
.sign_buffer = sign_buffer_gpg ,
72
75
.get_default_key = NULL ,
76
+ .get_key_id = NULL ,
73
77
},
74
78
{
75
79
.name = "x509" ,
@@ -79,6 +83,7 @@ static struct gpg_format gpg_format[] = {
79
83
.verify_signed_buffer = verify_gpg_signed_buffer ,
80
84
.sign_buffer = sign_buffer_gpg ,
81
85
.get_default_key = NULL ,
86
+ .get_key_id = NULL ,
82
87
},
83
88
{
84
89
.name = "ssh" ,
@@ -88,6 +93,7 @@ static struct gpg_format gpg_format[] = {
88
93
.verify_signed_buffer = NULL , /* TODO */
89
94
.sign_buffer = sign_buffer_ssh ,
90
95
.get_default_key = get_default_ssh_signing_key ,
96
+ .get_key_id = get_ssh_key_id ,
91
97
},
92
98
};
93
99
@@ -484,6 +490,41 @@ int git_gpg_config(const char *var, const char *value, void *cb)
484
490
return 0 ;
485
491
}
486
492
493
+ static char * get_ssh_key_fingerprint (const char * signing_key )
494
+ {
495
+ struct child_process ssh_keygen = CHILD_PROCESS_INIT ;
496
+ int ret = -1 ;
497
+ struct strbuf fingerprint_stdout = STRBUF_INIT ;
498
+ struct strbuf * * fingerprint ;
499
+
500
+ /*
501
+ * With SSH Signing this can contain a filename or a public key
502
+ * For textual representation we usually want a fingerprint
503
+ */
504
+ if (starts_with (signing_key , "ssh-" )) {
505
+ strvec_pushl (& ssh_keygen .args , "ssh-keygen" , "-lf" , "-" , NULL );
506
+ ret = pipe_command (& ssh_keygen , signing_key ,
507
+ strlen (signing_key ), & fingerprint_stdout , 0 ,
508
+ NULL , 0 );
509
+ } else {
510
+ strvec_pushl (& ssh_keygen .args , "ssh-keygen" , "-lf" ,
511
+ configured_signing_key , NULL );
512
+ ret = pipe_command (& ssh_keygen , NULL , 0 , & fingerprint_stdout , 0 ,
513
+ NULL , 0 );
514
+ }
515
+
516
+ if (!!ret )
517
+ die_errno (_ ("failed to get the ssh fingerprint for key '%s'" ),
518
+ signing_key );
519
+
520
+ fingerprint = strbuf_split_max (& fingerprint_stdout , ' ' , 3 );
521
+ if (!fingerprint [1 ])
522
+ die_errno (_ ("failed to get the ssh fingerprint for key '%s'" ),
523
+ signing_key );
524
+
525
+ return strbuf_detach (fingerprint [1 ], NULL );
526
+ }
527
+
487
528
/* Returns the first public key from an ssh-agent to use for signing */
488
529
static const char * get_default_ssh_signing_key (void )
489
530
{
@@ -532,6 +573,21 @@ static const char *get_default_ssh_signing_key(void)
532
573
return default_key ;
533
574
}
534
575
576
+ static const char * get_ssh_key_id (void ) {
577
+ return get_ssh_key_fingerprint (get_signing_key ());
578
+ }
579
+
580
+ /* Returns a textual but unique representation of the signing key */
581
+ const char * get_signing_key_id (void )
582
+ {
583
+ if (use_format -> get_key_id ) {
584
+ return use_format -> get_key_id ();
585
+ }
586
+
587
+ /* GPG/GPGSM only store a key id on this variable */
588
+ return get_signing_key ();
589
+ }
590
+
535
591
const char * get_signing_key (void )
536
592
{
537
593
if (configured_signing_key )
0 commit comments