@@ -19,8 +19,8 @@ struct gpg_format {
19
19
const char * * verify_args ;
20
20
const char * * sigs ;
21
21
int (* verify_signed_buffer )(struct signature_check * sigc ,
22
- struct gpg_format * fmt , const char * payload ,
23
- size_t payload_size , const char * signature ,
22
+ struct gpg_format * fmt ,
23
+ const char * signature ,
24
24
size_t signature_size );
25
25
int (* sign_buffer )(struct strbuf * buffer , struct strbuf * signature ,
26
26
const char * signing_key );
@@ -53,12 +53,12 @@ static const char *ssh_sigs[] = {
53
53
};
54
54
55
55
static int verify_gpg_signed_buffer (struct signature_check * sigc ,
56
- struct gpg_format * fmt , const char * payload ,
57
- size_t payload_size , const char * signature ,
56
+ struct gpg_format * fmt ,
57
+ const char * signature ,
58
58
size_t signature_size );
59
59
static int verify_ssh_signed_buffer (struct signature_check * sigc ,
60
- struct gpg_format * fmt , const char * payload ,
61
- size_t payload_size , const char * signature ,
60
+ struct gpg_format * fmt ,
61
+ const char * signature ,
62
62
size_t signature_size );
63
63
static int sign_buffer_gpg (struct strbuf * buffer , struct strbuf * signature ,
64
64
const char * signing_key );
@@ -314,8 +314,8 @@ static void parse_gpg_output(struct signature_check *sigc)
314
314
}
315
315
316
316
static int verify_gpg_signed_buffer (struct signature_check * sigc ,
317
- struct gpg_format * fmt , const char * payload ,
318
- size_t payload_size , const char * signature ,
317
+ struct gpg_format * fmt ,
318
+ const char * signature ,
319
319
size_t signature_size )
320
320
{
321
321
struct child_process gpg = CHILD_PROCESS_INIT ;
@@ -343,14 +343,13 @@ static int verify_gpg_signed_buffer(struct signature_check *sigc,
343
343
NULL );
344
344
345
345
sigchain_push (SIGPIPE , SIG_IGN );
346
- ret = pipe_command (& gpg , payload , payload_size , & gpg_stdout , 0 ,
346
+ ret = pipe_command (& gpg , sigc -> payload , sigc -> payload_len , & gpg_stdout , 0 ,
347
347
& gpg_stderr , 0 );
348
348
sigchain_pop (SIGPIPE );
349
349
350
350
delete_tempfile (& temp );
351
351
352
352
ret |= !strstr (gpg_stdout .buf , "\n[GNUPG:] GOODSIG " );
353
- sigc -> payload = xmemdupz (payload , payload_size );
354
353
sigc -> output = strbuf_detach (& gpg_stderr , NULL );
355
354
sigc -> gpg_status = strbuf_detach (& gpg_stdout , NULL );
356
355
@@ -426,8 +425,8 @@ static void parse_ssh_output(struct signature_check *sigc)
426
425
}
427
426
428
427
static int verify_ssh_signed_buffer (struct signature_check * sigc ,
429
- struct gpg_format * fmt , const char * payload ,
430
- size_t payload_size , const char * signature ,
428
+ struct gpg_format * fmt ,
429
+ const char * signature ,
431
430
size_t signature_size )
432
431
{
433
432
struct child_process ssh_keygen = CHILD_PROCESS_INIT ;
@@ -440,6 +439,13 @@ static int verify_ssh_signed_buffer(struct signature_check *sigc,
440
439
struct strbuf ssh_principals_err = STRBUF_INIT ;
441
440
struct strbuf ssh_keygen_out = STRBUF_INIT ;
442
441
struct strbuf ssh_keygen_err = STRBUF_INIT ;
442
+ struct strbuf verify_time = STRBUF_INIT ;
443
+ const struct date_mode verify_date_mode = {
444
+ .type = DATE_STRFTIME ,
445
+ .strftime_fmt = "%Y%m%d%H%M%S" ,
446
+ /* SSH signing key validity has no timezone information - Use the local timezone */
447
+ .local = 1 ,
448
+ };
443
449
444
450
if (!ssh_allowed_signers ) {
445
451
error (_ ("gpg.ssh.allowedSignersFile needs to be configured and exist for ssh signature verification" ));
@@ -457,11 +463,16 @@ static int verify_ssh_signed_buffer(struct signature_check *sigc,
457
463
return -1 ;
458
464
}
459
465
466
+ if (sigc -> payload_timestamp )
467
+ strbuf_addf (& verify_time , "-Overify-time=%s" ,
468
+ show_date (sigc -> payload_timestamp , 0 , & verify_date_mode ));
469
+
460
470
/* Find the principal from the signers */
461
471
strvec_pushl (& ssh_keygen .args , fmt -> program ,
462
472
"-Y" , "find-principals" ,
463
473
"-f" , ssh_allowed_signers ,
464
474
"-s" , buffer_file -> filename .buf ,
475
+ verify_time .buf ,
465
476
NULL );
466
477
ret = pipe_command (& ssh_keygen , NULL , 0 , & ssh_principals_out , 0 ,
467
478
& ssh_principals_err , 0 );
@@ -479,8 +490,9 @@ static int verify_ssh_signed_buffer(struct signature_check *sigc,
479
490
"-Y" , "check-novalidate" ,
480
491
"-n" , "git" ,
481
492
"-s" , buffer_file -> filename .buf ,
493
+ verify_time .buf ,
482
494
NULL );
483
- pipe_command (& ssh_keygen , payload , payload_size ,
495
+ pipe_command (& ssh_keygen , sigc -> payload , sigc -> payload_len ,
484
496
& ssh_keygen_out , 0 , & ssh_keygen_err , 0 );
485
497
486
498
/*
@@ -513,6 +525,7 @@ static int verify_ssh_signed_buffer(struct signature_check *sigc,
513
525
"-f" , ssh_allowed_signers ,
514
526
"-I" , principal ,
515
527
"-s" , buffer_file -> filename .buf ,
528
+ verify_time .buf ,
516
529
NULL );
517
530
518
531
if (ssh_revocation_file ) {
@@ -526,7 +539,7 @@ static int verify_ssh_signed_buffer(struct signature_check *sigc,
526
539
}
527
540
528
541
sigchain_push (SIGPIPE , SIG_IGN );
529
- ret = pipe_command (& ssh_keygen , payload , payload_size ,
542
+ ret = pipe_command (& ssh_keygen , sigc -> payload , sigc -> payload_len ,
530
543
& ssh_keygen_out , 0 , & ssh_keygen_err , 0 );
531
544
sigchain_pop (SIGPIPE );
532
545
@@ -540,7 +553,6 @@ static int verify_ssh_signed_buffer(struct signature_check *sigc,
540
553
}
541
554
}
542
555
543
- sigc -> payload = xmemdupz (payload , payload_size );
544
556
strbuf_stripspace (& ssh_keygen_out , 0 );
545
557
strbuf_stripspace (& ssh_keygen_err , 0 );
546
558
/* Add stderr outputs to show the user actual ssh-keygen errors */
@@ -558,12 +570,48 @@ static int verify_ssh_signed_buffer(struct signature_check *sigc,
558
570
strbuf_release (& ssh_principals_err );
559
571
strbuf_release (& ssh_keygen_out );
560
572
strbuf_release (& ssh_keygen_err );
573
+ strbuf_release (& verify_time );
561
574
562
575
return ret ;
563
576
}
564
577
565
- int check_signature (const char * payload , size_t plen , const char * signature ,
566
- size_t slen , struct signature_check * sigc )
578
+ static int parse_payload_metadata (struct signature_check * sigc )
579
+ {
580
+ const char * ident_line = NULL ;
581
+ size_t ident_len ;
582
+ struct ident_split ident ;
583
+ const char * signer_header ;
584
+
585
+ switch (sigc -> payload_type ) {
586
+ case SIGNATURE_PAYLOAD_COMMIT :
587
+ signer_header = "committer" ;
588
+ break ;
589
+ case SIGNATURE_PAYLOAD_TAG :
590
+ signer_header = "tagger" ;
591
+ break ;
592
+ case SIGNATURE_PAYLOAD_UNDEFINED :
593
+ case SIGNATURE_PAYLOAD_PUSH_CERT :
594
+ /* Ignore payloads we don't want to parse */
595
+ return 0 ;
596
+ default :
597
+ BUG ("invalid value for sigc->payload_type" );
598
+ }
599
+
600
+ ident_line = find_commit_header (sigc -> payload , signer_header , & ident_len );
601
+ if (!ident_line || !ident_len )
602
+ return 1 ;
603
+
604
+ if (split_ident_line (& ident , ident_line , ident_len ))
605
+ return 1 ;
606
+
607
+ if (!sigc -> payload_timestamp && ident .date_begin && ident .date_end )
608
+ sigc -> payload_timestamp = parse_timestamp (ident .date_begin , NULL , 10 );
609
+
610
+ return 0 ;
611
+ }
612
+
613
+ int check_signature (struct signature_check * sigc ,
614
+ const char * signature , size_t slen )
567
615
{
568
616
struct gpg_format * fmt ;
569
617
int status ;
@@ -575,8 +623,10 @@ int check_signature(const char *payload, size_t plen, const char *signature,
575
623
if (!fmt )
576
624
die (_ ("bad/incompatible signature '%s'" ), signature );
577
625
578
- status = fmt -> verify_signed_buffer (sigc , fmt , payload , plen , signature ,
579
- slen );
626
+ if (parse_payload_metadata (sigc ))
627
+ return 1 ;
628
+
629
+ status = fmt -> verify_signed_buffer (sigc , fmt , signature , slen );
580
630
581
631
if (status && !sigc -> output )
582
632
return !!status ;
@@ -593,7 +643,7 @@ void print_signature_buffer(const struct signature_check *sigc, unsigned flags)
593
643
sigc -> output ;
594
644
595
645
if (flags & GPG_VERIFY_VERBOSE && sigc -> payload )
596
- fputs (sigc -> payload , stdout );
646
+ fwrite (sigc -> payload , 1 , sigc -> payload_len , stdout );
597
647
598
648
if (output )
599
649
fputs (output , stderr );
0 commit comments