39
39
gpgme_ctx_t context = NULL;
41
41
retvalue gpgerror(gpg_error_t err) {
43
43
fprintf(stderr, "gpgme gave error %s:%d: %s\n",
44
44
gpg_strsource(err), gpg_err_code(err),
45
45
gpg_strerror(err));
46
if( gpg_err_code(err) == GPG_ERR_ENOMEM )
46
if (gpg_err_code(err) == GPG_ERR_ENOMEM)
47
47
return RET_ERROR_OOM;
49
49
return RET_ERROR_GPGME;
73
73
#ifdef HAVE_LIBGPGME
77
77
return RET_NOTHING;
78
78
gpgme_check_version(NULL);
79
79
err = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP);
81
81
return gpgerror(err);
82
82
err = gpgme_new(&context);
85
err = gpgme_set_protocol(context,GPGME_PROTOCOL_OpenPGP);
89
gpgme_set_passphrase_cb(context,signature_getpassphrase,NULL);
90
gpgme_set_armor(context,1);
85
err = gpgme_set_protocol(context, GPGME_PROTOCOL_OpenPGP);
89
gpgme_set_passphrase_cb(context, signature_getpassphrase,
91
gpgme_set_armor(context, 1);
91
92
#endif /* HAVE_LIBGPGME */
95
96
void signatures_done(void) {
96
97
#ifdef HAVE_LIBGPGME
97
if( context != NULL ) {
98
if (context != NULL) {
98
99
gpgme_release(context);
110
111
signresult = gpgme_op_sign_result(context);
111
if( signresult != NULL && signresult->signatures != NULL )
112
if (signresult != NULL && signresult->signatures != NULL)
113
114
/* in an ideal world, this point is never reached.
114
115
* Sadly it is and people are obviously confused by it,
115
116
* so do some work to give helpful messages. */
116
if( options != NULL ) {
117
if (options != NULL) {
117
118
assert (options->count > 0);
118
119
uidoptions = mprintf(" -u '%s'", options->values[0]);
120
121
uidoptions != NULL && i < options->count ;
122
123
char *u = mprintf("%s -u '%s'", uidoptions,
123
124
options->values[0]);
124
125
free(uidoptions);
127
if( FAILEDTOALLOC(uidoptions) )
128
if (FAILEDTOALLOC(uidoptions))
128
129
return RET_ERROR_OOM;
130
131
uidoptions = NULL;
132
if( signresult == NULL )
133
if (signresult == NULL)
134
135
"Error: gpgme returned NULL unexpectedly for gpgme_op_sign_result\n", stderr);
136
fputs( "Error: gpgme created no signature!\n", stderr);
137
fputs("Error: gpgme created no signature!\n", stderr);
138
139
"This most likely means gpg is confused or produces some error libgpgme is\n"
139
140
"not able to understand. Try running\n", stderr);
142
143
"gpg %s --output 'some-other-file' %s 'some-file'\n",
143
144
(uidoptions==NULL)?"":uidoptions,
165
166
signature_data = gpgme_data_release_and_get_mem(dh_gpg, &signature_len);
166
if( signature_data == NULL )
167
if (FAILEDTOALLOC(signature_data))
167
168
return RET_ERROR_OOM;
168
169
fd = open(signaturename, O_WRONLY|O_CREAT|O_EXCL|O_NOCTTY|O_NOFOLLOW, 0666);
170
171
free(signature_data);
171
172
return RET_ERRNO(errno);
173
174
p = signature_data;
174
while( signature_len > 0 ) {
175
while (signature_len > 0) {
175
176
written = write(fd, p, signature_len);
178
179
fprintf(stderr, "Error %d writing to %s: %s\n",
179
180
e, signaturename,
212
213
err = gpgme_data_new(&dh_gpg);
214
215
return gpgerror(err);
215
216
err = gpgme_op_sign(context, dh, dh_gpg,
216
217
clearsign?GPGME_SIG_MODE_CLEAR:GPGME_SIG_MODE_DETACH);
218
219
return gpgerror(err);
219
220
r = check_signature_created(clearsign, willcleanup,
220
221
options, filename, signaturename);
221
if( RET_WAS_ERROR(r) ) {
222
if (RET_WAS_ERROR(r)) {
222
223
gpgme_data_release(dh_gpg);
237
238
#endif /* HAVE_LIBGPGME */
239
assert( options != NULL && options->count > 0 );
240
assert (options != NULL && options->count > 0);
241
242
r = signature_init(false);
242
if( RET_WAS_ERROR(r) )
243
if (RET_WAS_ERROR(r))
245
246
/* make sure it does not already exists */
247
248
ret = unlink(signaturename);
248
if( ret != 0 && (e = errno) != ENOENT ) {
249
fprintf(stderr, "Could not remove '%s' to prepare replacement: %s\n",
249
if (ret != 0 && (e = errno) != ENOENT) {
251
"Could not remove '%s' to prepare replacement: %s\n",
250
252
signaturename, strerror(e));
251
253
return RET_ERROR;
253
255
ret = unlink(clearsignfilename);
254
if( ret != 0 && (e = errno) != ENOENT ) {
255
fprintf(stderr, "Could not remove '%s' to prepare replacement: %s\n",
256
if (ret != 0 && (e = errno) != ENOENT) {
258
"Could not remove '%s' to prepare replacement: %s\n",
256
259
clearsignfilename, strerror(e));
257
260
return RET_ERROR;
260
if( options->values[0][0] == '!' ) {
263
if (options->values[0][0] == '!') {
261
264
// TODO: allow external programs, too
262
fprintf(stderr, "sign-scripts (starting with '!') not allowed yet.\n");
266
"sign-scripts (starting with '!') not allowed yet.\n");
263
267
return RET_ERROR;
265
269
#ifdef HAVE_LIBGPGME
266
270
gpgme_signers_clear(context);
267
if( options->count == 1 &&
271
if (options->count == 1 &&
268
272
(strcasecmp(options->values[0], "yes") == 0 ||
269
strcasecmp(options->values[0], "default") == 0) ) {
273
strcasecmp(options->values[0], "default") == 0)) {
270
274
/* use default options */
272
} else for( i = 0 ; i < options->count ; i++ ) {
276
} else for (i = 0 ; i < options->count ; i++) {
273
277
const char *option = options->values[i];
276
280
err = gpgme_op_keylist_start(context, option, 1);
278
282
return gpgerror(err);
279
283
err = gpgme_op_keylist_next(context, &key);
280
if( gpg_err_code(err) == GPG_ERR_EOF ) {
281
fprintf(stderr, "Could not find any key matching '%s'!\n", option);
284
if (gpg_err_code(err) == GPG_ERR_EOF) {
286
"Could not find any key matching '%s'!\n", option);
282
287
return RET_ERROR;
284
289
err = gpgme_signers_add(context, key);
285
290
gpgme_key_unref(key);
287
292
gpgme_op_keylist_end(context);
288
293
return gpgerror(err);
293
298
err = gpgme_data_new_from_mem(&dh, data, datalen, 0);
295
300
return gpgerror(err);
298
303
r = create_signature(false, dh, options,
299
304
filename, signaturename, willcleanup);
300
if( RET_WAS_ERROR(r) ) {
305
if (RET_WAS_ERROR(r)) {
301
306
gpgme_data_release(dh);
304
309
i = gpgme_data_seek(dh, 0, SEEK_SET);
308
313
"Error %d rewinding gpgme's data buffer to start: %s\n",
338
343
struct signature *sig;
340
345
result = gpgme_op_verify_result(context);
341
if( result == NULL ) {
342
fprintf(stderr,"Internal error communicating with libgpgme: no result record!\n\n");
346
if (result == NULL) {
348
"Internal error communicating with libgpgme: no result record!\n\n");
343
349
return RET_ERROR_GPGME;
345
if( signatures_p != NULL ) {
351
if (signatures_p != NULL) {
347
for( s = result->signatures ; s != NULL ; s = s->next ) {
353
for (s = result->signatures ; s != NULL ; s = s->next) {
350
356
signatures = calloc(1, sizeof(struct signatures) +
351
357
count * sizeof(struct signature));
352
if( FAILEDTOALLOC(signatures) )
358
if (FAILEDTOALLOC(signatures))
353
359
return RET_ERROR_OOM;
354
360
signatures->count = count;
355
361
signatures->validcount = 0;
358
364
signatures = NULL;
361
for( s = result->signatures ; s != NULL ; s = s->next ) {
367
for (s = result->signatures ; s != NULL ; s = s->next) {
362
368
enum signature_state state = sist_error;
364
if( signatures_p != NULL ) {
370
if (signatures_p != NULL) {
365
371
sig->keyid = strdup(s->fpr);
366
if( FAILEDTOALLOC(sig->keyid) ) {
372
if (FAILEDTOALLOC(sig->keyid)) {
367
373
signatures_free(signatures);
368
374
return RET_ERROR_OOM;
371
switch( gpg_err_code(s->status) ) {
377
switch (gpg_err_code(s->status)) {
372
378
case GPG_ERR_NO_ERROR:
373
379
had_valid = true;
374
380
state = sist_valid;
376
382
signatures->validcount++;
378
384
case GPG_ERR_KEY_EXPIRED:
379
385
had_valid = true;
382
388
"Ignoring signature with '%s' on '%s', as the key has expired.\n",
383
389
s->fpr, filename);
384
390
state = sist_mostly;
386
392
sig->expired_key = true;
388
394
case GPG_ERR_CERT_REVOKED:
389
395
had_valid = true;
392
398
"Ignoring signature with '%s' on '%s', as the key is revoked.\n",
393
399
s->fpr, filename);
394
400
state = sist_mostly;
396
402
sig->revoced_key = true;
398
404
case GPG_ERR_SIG_EXPIRED:
399
405
had_valid = true;
401
407
time_t timestamp = s->timestamp,
402
408
exp_timestamp = s->exp_timestamp;
467
473
valid if the primary key is expired */
470
for( i = 0 ; i < signatures->count ; i++ ) {
476
for (i = 0 ; i < signatures->count ; i++) {
472
478
gpgme_key_t gpgme_key = NULL;
473
479
gpgme_subkey_t subkey;
474
480
struct signature *sig = &signatures->signatures[i];
476
if( sig->state == sist_error || sig->state == sist_missing ) {
482
if (sig->state == sist_error || sig->state == sist_missing) {
477
483
sig->primary_keyid = strdup(sig->keyid);
478
if( FAILEDTOALLOC(sig->primary_keyid) )
484
if (FAILEDTOALLOC(sig->primary_keyid))
479
485
return RET_ERROR_OOM;
483
489
err = gpgme_get_key(context, sig->keyid, &gpgme_key, 0);
485
fprintf(stderr, "gpgme error %s:%d retrieving key '%s': %s\n",
486
gpg_strsource(err), (int)gpg_err_code(err),
492
"gpgme error %s:%d retrieving key '%s': %s\n",
494
(int)gpg_err_code(err),
487
495
sig->keyid, gpg_strerror(err));
488
if( gpg_err_code(err) == GPG_ERR_ENOMEM )
496
if (gpg_err_code(err) == GPG_ERR_ENOMEM)
489
497
return RET_ERROR_OOM;
491
499
return RET_ERROR_GPGME;
493
assert( gpgme_key != NULL );
501
assert (gpgme_key != NULL);
494
502
/* the first "sub"key is the primary key */
495
503
subkey = gpgme_key->subkeys;
496
if( subkey->revoked ) {
504
if (subkey->revoked) {
497
505
sig->revoced_key = true;
498
if( sig->state == sist_valid ) {
506
if (sig->state == sist_valid) {
499
507
sig->state = sist_mostly;
500
508
signatures->validcount--;
503
if( subkey->expired ) {
511
if (subkey->expired) {
504
512
sig->expired_key = true;
505
if( sig->state == sist_valid ) {
513
if (sig->state == sist_valid) {
506
514
sig->state = sist_mostly;
507
515
signatures->validcount--;
510
518
sig->primary_keyid = strdup(subkey->keyid);
511
519
gpgme_key_unref(gpgme_key);
512
if( FAILEDTOALLOC(sig->primary_keyid) )
520
if (FAILEDTOALLOC(sig->primary_keyid))
513
521
return RET_ERROR_OOM;
517
525
#endif /* HAVE_LIBGPGME */
519
527
static inline void extractchunk(const char *buffer, const char **begin, const char **end, const char **next) {
520
const char *startofchanges,*endofchanges,*afterchanges;
528
const char *startofchanges, *endofchanges, *afterchanges;
522
530
startofchanges = buffer;
523
while( *startofchanges == ' ' || *startofchanges == '\t' ||
524
*startofchanges == '\r' || *startofchanges =='\n' )
531
while (*startofchanges == ' ' || *startofchanges == '\t' ||
532
*startofchanges == '\r' || *startofchanges =='\n')
525
533
startofchanges++;
527
535
endofchanges = startofchanges;
528
536
afterchanges = NULL;
529
while( *endofchanges != '\0' ) {
530
if( *endofchanges == '\n' ) {
537
while (*endofchanges != '\0') {
538
if (*endofchanges == '\n') {
532
540
afterchanges = endofchanges;
533
while( *afterchanges =='\r' )
541
while (*afterchanges =='\r')
535
if( *afterchanges == '\n' )
543
if (*afterchanges == '\n')
537
545
endofchanges = afterchanges;
538
546
afterchanges = NULL;
566
574
#ifdef HAVE_LIBGPGME
567
575
static retvalue extract_signed_data(const char *buffer, size_t bufferlen, const char *filenametoshow, char **chunkread, /*@null@*/ /*@out@*/struct signatures **signatures_p, bool *brokensignature, bool *failed) {
568
const char *startofchanges,*endofchanges,*afterchanges;
576
const char *startofchanges, *endofchanges, *afterchanges;
571
gpgme_data_t dh,dh_gpg;
579
gpgme_data_t dh, dh_gpg;
572
580
size_t plain_len;
573
581
char *plain_data;
576
584
bool foundbroken = false;
578
586
r = signature_init(false);
579
if( RET_WAS_ERROR(r) )
587
if (RET_WAS_ERROR(r))
582
590
err = gpgme_data_new_from_mem(&dh_gpg, buffer, bufferlen, 0);
584
592
return gpgerror(err);
586
594
err = gpgme_data_new(&dh);
588
596
gpgme_data_release(dh_gpg);
589
597
return gpgerror(err);
591
599
err = gpgme_op_verify(context, dh_gpg, NULL, dh);
592
if( gpg_err_code(err) == GPG_ERR_NO_DATA ) {
594
fprintf(stderr,"Data seems not to be signed trying to use directly....\n");
600
if (gpg_err_code(err) == GPG_ERR_NO_DATA) {
603
"Data seems not to be signed trying to use directly....\n");
595
604
gpgme_data_release(dh);
596
605
gpgme_data_release(dh_gpg);
597
606
return RET_NOTHING;
600
609
gpgme_data_release(dh_gpg);
601
610
gpgme_data_release(dh);
602
611
return gpgerror(err);
604
if( signatures_p != NULL || brokensignature != NULL ) {
613
if (signatures_p != NULL || brokensignature != NULL) {
605
614
r = checksigs(filenametoshow,
606
615
(signatures_p!=NULL)?&signatures:NULL,
607
616
(brokensignature!=NULL)?&foundbroken:NULL);
608
if( RET_WAS_ERROR(r) ) {
617
if (RET_WAS_ERROR(r)) {
609
618
gpgme_data_release(dh_gpg);
610
619
gpgme_data_release(dh);
614
623
gpgme_data_release(dh_gpg);
615
plain_data = gpgme_data_release_and_get_mem(dh,&plain_len);
616
if( plain_data == NULL ) {
624
plain_data = gpgme_data_release_and_get_mem(dh, &plain_len);
625
if (plain_data == NULL) {
618
627
"(not yet fatal) ERROR: libgpgme failed to extract the plain data out of\n"
626
635
signatures_free(signatures);
627
636
return RET_NOTHING;
629
if( signatures != NULL ) {
638
if (signatures != NULL) {
630
639
r = check_primary_keys(signatures);
631
if( RET_WAS_ERROR(r) ) {
640
if (RET_WAS_ERROR(r)) {
632
641
signatures_free(signatures);
638
if( plain_data == NULL )
647
if (FAILEDTOALLOC(plain_data))
639
648
r = RET_ERROR_OOM;
641
650
// TODO: check if the new extractchunk can be used...
643
652
startofchanges = plain_data;
644
while( (size_t)(startofchanges - plain_data) < plain_len &&
645
*startofchanges != '\0' && xisspace(*startofchanges)) {
653
while ((size_t)(startofchanges - plain_data) < plain_len
654
&& *startofchanges != '\0'
655
&& xisspace(*startofchanges)) {
646
656
startofchanges++;
648
if( (size_t)(startofchanges - plain_data) >= plain_len ) {
658
if ((size_t)(startofchanges - plain_data) >= plain_len) {
650
660
"Could only find spaces within '%s'!\n",
657
667
endofchanges = startofchanges;
658
while( (size_t)(endofchanges - plain_data) < plain_len &&
668
while ((size_t)(endofchanges - plain_data) < plain_len &&
659
669
*endofchanges != '\0' &&
660
( *endofchanges != '\n' || *(endofchanges-1)!= '\n')) {
670
(*endofchanges != '\n'
671
|| *(endofchanges-1)!= '\n')) {
663
674
afterchanges = endofchanges;
664
while( (size_t)(afterchanges - plain_data) < plain_len &&
665
*afterchanges != '\0' && xisspace(*afterchanges)) {
675
while ((size_t)(afterchanges - plain_data) < plain_len
676
&& *afterchanges != '\0'
677
&& xisspace(*afterchanges)) {
668
if( (size_t)(afterchanges - plain_data) != plain_len ) {
669
if( *afterchanges == '\0' )
680
if ((size_t)(afterchanges - plain_data) != plain_len) {
681
if (*afterchanges == '\0')
671
683
"Unexpected \\0 character within '%s'!\n",
690
702
free(plain_data);
693
if( signatures_p != NULL )
705
if (signatures_p != NULL)
694
706
*signatures_p = signatures;
695
if( brokensignature != NULL )
707
if (brokensignature != NULL)
696
708
*brokensignature = foundbroken;
698
710
signatures_free(signatures);
704
716
/* Read a single chunk from a file, that may be signed. */
705
717
retvalue signature_readsignedchunk(const char *filename, const char *filenametoshow, char **chunkread, /*@null@*/ /*@out@*/struct signatures **signatures_p, bool *brokensignature) {
706
718
char *chunk, *h, *afterchunk;
707
const char *startofchanges,*endofchanges,*afterchanges;
719
const char *startofchanges, *endofchanges, *afterchanges;
708
720
size_t chunklen, len;
710
722
bool failed = false;
712
724
r = readtextfile(filename, filenametoshow, &chunk, &chunklen);
716
if( chunklen == 0 ) {
717
729
fprintf(stderr, "Unexpected empty file '%s'!\n",
731
743
/* fast-track unsigned chunks: */
732
if( startofchanges[0] != '-' && *afterchanges == '\0' ) {
734
fprintf(stderr,"Data seems not to be signed trying to use directly...\n");
744
if (startofchanges[0] != '-' && *afterchanges == '\0') {
745
if (verbose > 5 && strncmp(startofchanges, "Format:", 7) != 0
746
&& strncmp(startofchanges, "Source:", 7) != 0)
748
"Data seems not to be signed trying to use directly...\n");
735
749
len = chunk_extract(chunk, chunk, &afterchunk);
736
assert( *afterchunk == '\0' );
737
assert( chunk[len] == '\0' );
750
assert (*afterchunk == '\0');
751
assert (chunk[len] == '\0');
738
752
h = realloc(chunk, len + 1);
741
755
*chunkread = chunk;
742
if( signatures_p != NULL )
756
if (signatures_p != NULL)
743
757
*signatures_p = NULL;
744
if( brokensignature != NULL )
758
if (brokensignature != NULL)
745
759
*brokensignature = false;
749
if( startofchanges[0] != '-' ) {
750
fprintf(stderr, "Error parsing '%s': Seems not to be signed but has spurious empty line.\n", filenametoshow);
763
if (startofchanges[0] != '-') {
765
"Error parsing '%s': Seems not to be signed but has spurious empty line.\n",
752
768
return RET_ERROR;
764
780
/* We have no libgpgme, it failed, or could not find signature data,
765
781
* trying to extract it manually, ignoring signatures: */
767
if( *afterchanges == '\0' ) {
783
if (*afterchanges == '\0') {
769
785
"First non-space character is a '-' but there is no empty line in\n"
773
789
return RET_ERROR;
775
if( strncmp(startofchanges, "-----BEGIN", 10) != 0 ) {
791
if (strncmp(startofchanges, "-----BEGIN", 10) != 0) {
777
793
"Strange content of '%s': First non-space character is '-',\n"
778
794
"but it does not begin with '-----BEGIN'.\n", filenametoshow);
788
804
len = chunk_extract(chunk, afterchanges, &afterchunk);
791
fprintf(stderr,"Could not find any data within '%s'!\n",
807
fprintf(stderr, "Could not find any data within '%s'!\n",
794
810
return RET_ERROR;
797
if( *afterchunk == '\0' ) {
813
if (*afterchunk == '\0') {
798
814
const char *endmarker;
800
816
endmarker = strstr(chunk, "\n-----");
801
if( endmarker != NULL ) {
817
if (endmarker != NULL) {
803
assert( (size_t)(endmarker-chunk) < len );
819
assert ((size_t)(endmarker-chunk) < len);
804
820
len = endmarker-chunk;
805
821
chunk[len] = '\0';
812
828
return RET_ERROR;
814
} else if( strncmp(afterchunk, "-----", 5) != 0 ) {
815
fprintf(stderr,"ERROR: Spurious empty line within '%s'.\n"
830
} else if (strncmp(afterchunk, "-----", 5) != 0) {
831
fprintf(stderr, "ERROR: Spurious empty line within '%s'.\n"
816
832
"Cannot determine what is data and what is not!\n",
819
835
return RET_ERROR;
822
assert( chunk[len] == '\0' );
838
assert (chunk[len] == '\0');
823
839
h = realloc(chunk, len + 1);
826
if( signatures_p != NULL ) {
842
if (signatures_p != NULL) {
827
843
/* pointer to structure with count 0 to make clear
828
844
* it is not unsigned */
829
845
*signatures_p = calloc(1, sizeof(struct signatures));
830
if( FAILEDTOALLOC(*signatures_p) ) {
846
if (FAILEDTOALLOC(*signatures_p)) {
832
848
return RET_ERROR_OOM;
835
851
*chunkread = chunk;
836
if( brokensignature != NULL )
852
if (brokensignature != NULL)
837
853
*brokensignature = false;
852
868
retvalue signature_startsignedfile(const char *directory, const char *basefilename, const char *inlinefilename, struct signedfile **out) {
853
869
struct signedfile *n;
855
n = calloc(1, sizeof(struct signedfile));
871
n = zNEW(struct signedfile);
872
if (FAILEDTOALLOC(n))
857
873
return RET_ERROR_OOM;
858
874
n->plainfilename = calc_dirconcat(directory, basefilename);
859
if( n->plainfilename == NULL ) {
875
if (FAILEDTOALLOC(n->plainfilename)) {
861
877
return RET_ERROR_OOM;
863
879
n->inlinefilename = calc_dirconcat(directory, inlinefilename);
864
if( n->inlinefilename == NULL ) {
880
if (FAILEDTOALLOC(n->inlinefilename)) {
865
881
free(n->plainfilename);
867
883
return RET_ERROR_OOM;
883
899
void signedfile_free(struct signedfile *f, bool cleanup) {
886
if( f->newplainfilename != NULL ) {
902
if (f->newplainfilename != NULL) {
888
904
(void)unlink(f->newplainfilename);
889
905
free(f->newplainfilename);
891
907
free(f->plainfilename);
892
if( f->newsignfilename != NULL ) {
908
if (f->newsignfilename != NULL) {
894
910
(void)unlink(f->newsignfilename);
895
911
free(f->newsignfilename);
897
913
free(f->signfilename);
898
if( f->newinlinefilename != NULL ) {
914
if (f->newinlinefilename != NULL) {
900
916
(void)unlink(f->newinlinefilename);
901
917
free(f->newinlinefilename);
911
927
void signedfile_write(struct signedfile *f, const void *data, size_t len) {
913
929
/* no need to try anything if there already was an error */
914
if( RET_WAS_ERROR(f->result) )
930
if (RET_WAS_ERROR(f->result))
917
if( len > f->buffersize - f->bufferlen ) {
933
if (len > f->buffersize - f->bufferlen) {
918
934
size_t blocks = (len + f->bufferlen)/DATABUFFERUNITS;
919
935
size_t newsize = (blocks + 1) * DATABUFFERUNITS;
922
938
/* realloc is wasteful, but should not happen too often */
923
939
newbuffer = realloc(f->buffer, newsize);
924
if( newbuffer == NULL ) {
940
if (FAILEDTOALLOC(newbuffer)) {
926
942
f->buffer = NULL;
927
943
f->result = RET_ERROR_OOM;
930
946
f->buffer = newbuffer;
931
947
f->buffersize = newsize;
932
assert( f->bufferlen < f->buffersize );
948
assert (f->bufferlen < f->buffersize);
934
assert( len <= f->buffersize - f->bufferlen );
950
assert (len <= f->buffersize - f->bufferlen);
935
951
memcpy(f->buffer + f->bufferlen, data, len);
936
952
f->bufferlen += len;
937
assert( f->bufferlen <= f->buffersize );
953
assert (f->bufferlen <= f->buffersize);
940
956
retvalue signedfile_prepare(struct signedfile *f, const struct strlist *options, bool willcleanup) {
944
if( RET_WAS_ERROR(f->result) )
960
if (RET_WAS_ERROR(f->result))
945
961
return f->result;
947
963
/* write content to file */
949
965
f->newplainfilename = calc_addsuffix(f->plainfilename, "new");
950
if( FAILEDTOALLOC(f->newplainfilename) )
966
if (FAILEDTOALLOC(f->newplainfilename))
951
967
return RET_ERROR_OOM;
953
969
(void)dirs_make_parent(f->newplainfilename);
954
970
(void)unlink(f->newplainfilename);
956
972
fd = open(f->newplainfilename, O_WRONLY|O_CREAT|O_TRUNC|O_NOCTTY, 0666);
959
975
fprintf(stderr, "Error creating file '%s': %s\n",
960
976
f->newplainfilename,
996
1012
return RET_ERRNO(e);
998
1014
/* now do the actual signing */
999
if( options != NULL && options->count > 0 ) {
1015
if (options != NULL && options->count > 0) {
1002
assert( f->newplainfilename != NULL );
1018
assert (f->newplainfilename != NULL);
1003
1019
f->signfilename = calc_addsuffix(f->plainfilename, "gpg");
1004
if( f->signfilename == NULL )
1020
if (FAILEDTOALLOC(f->signfilename))
1005
1021
return RET_ERROR_OOM;
1006
1022
f->newsignfilename = calc_addsuffix(f->signfilename, "new");
1007
if( f->newsignfilename == NULL )
1023
if (FAILEDTOALLOC(f->newsignfilename))
1008
1024
return RET_ERROR_OOM;
1009
1025
f->newinlinefilename = calc_addsuffix(f->inlinefilename, "new");
1010
if( FAILEDTOALLOC(f->newinlinefilename) )
1026
if (FAILEDTOALLOC(f->newinlinefilename))
1011
1027
return RET_ERROR_OOM;
1013
1029
r = signature_sign(options,
1026
1042
retvalue result = RET_OK, r;
1029
if( f->newsignfilename != NULL && f->signfilename != NULL ) {
1045
if (f->newsignfilename != NULL && f->signfilename != NULL) {
1030
1046
e = rename(f->newsignfilename, f->signfilename);
1033
1049
fprintf(stderr, "Error %d moving %s to %s: %s!\n", e,
1034
1050
f->newsignfilename,