2 #include <glib/gprintf.h>
6 #include <openssl/sha.h>
9 #include <linux/limits.h>
15 #include "appimage/appimage.h"
16 #include "appimage/appimage_shared.h"
17 #include "light_elf.h"
19 typedef unsigned char byte
;
21 char segment_name
[] = ".sha256_sig";
23 int sha256_file(char *path
, char outputBuffer
[65], int skip_offset
, int skip_length
)
25 FILE *file
= fopen(path
, "rb");
27 byte hash
[SHA256_DIGEST_LENGTH
];
30 const int bufSize
= 1024*1024;
31 byte
*buffer
= malloc(bufSize
);
38 int totalBytesRead
= 0;
39 if(skip_offset
<= bufSize
){
40 bytesRead
= fread(buffer
, 1, skip_offset
, file
);
41 totalBytesRead
+= bytesRead
;
42 // printf("totalBytesRead: %i\n", totalBytesRead);
43 // printf("bytesRead: %i\n", bytesRead);
44 SHA256_Update(&sha256
, buffer
, bytesRead
);
46 int stillToRead
= skip_offset
-bytesRead
;
47 // printf("Initial stillToRead: %i\n", stillToRead);
50 if(stillToRead
>bufSize
){
51 readThisTime
= bufSize
;
53 readThisTime
= stillToRead
;
55 while((bytesRead
= fread(buffer
, 1, readThisTime
, file
)))
57 totalBytesRead
+= bytesRead
;
58 // printf("totalBytesRead: %i\n", totalBytesRead);
59 // printf("readThisTime: %i\n", readThisTime);
60 // printf("bytesRead: %i\n", bytesRead);
61 SHA256_Update(&sha256
, buffer
, bytesRead
);
62 stillToRead
= skip_offset
-totalBytesRead
;
63 // printf("stillToRead: %i\n", stillToRead);
65 if(stillToRead
>bufSize
){
66 readThisTime
= bufSize
;
68 readThisTime
= stillToRead
;
73 fseek(file
, skip_offset
+skip_length
, SEEK_SET
);
75 /* Instead of the skipped area, calculate the sha256 of the same amount if 0x00s */
77 for(i
= 0; i
< skip_length
; i
++) {
78 SHA256_Update(&sha256
, "\0", 1);
82 while((bytesRead
= fread(buffer
, 1, bufSize
, file
)))
84 totalBytesRead
+= bytesRead
;
85 // printf("totalBytesRead: %i\n", totalBytesRead);
86 // printf("bytesRead: %i\n", bytesRead);
87 SHA256_Update(&sha256
, buffer
, bytesRead
);
89 SHA256_Final(hash
, &sha256
);
91 // fprintf(stderr, "totalBytesRead: %i\n", totalBytesRead);
93 for(i
= 0; i
< SHA256_DIGEST_LENGTH
; i
++)
95 sprintf(outputBuffer
+ (i
* 2), "%02x", hash
[i
]);
104 int main(int argc
,char **argv
) {
106 fprintf(stderr
, "Usage: %s Signed.AppImage\n", argv
[0]);
110 char *filename
= argv
[1];
112 unsigned long skip_offset
= 0;
113 unsigned long skip_length
= 0;
115 if (!appimage_get_elf_section_offset_and_length(filename
, ".sha256_sig", &skip_offset
, &skip_length
)) {
116 fprintf(stderr
, "Failed to read .sha256_sig section");
120 if(skip_length
> 0) {
121 fprintf(stderr
, "Skipping ELF section %s with offset %lu, length %lu\n", segment_name
, skip_offset
, skip_length
);
123 fprintf(stderr
, "ELF section %s not found, is the file signed?\n", segment_name
);
128 digestfile
= g_strconcat("/tmp/", basename(g_strconcat(filename
, ".digest", NULL
)), NULL
);
130 signaturefile
= g_strconcat("/tmp/", basename(g_strconcat(filename
, ".sig", NULL
)), NULL
);
132 uint8_t *data
= malloc(skip_length
);
134 FILE* fd
= fopen(filename
, "r");
135 fseek(fd
, skip_offset
, SEEK_SET
);
136 fread(data
, skip_length
, sizeof(uint8_t), fd
);
138 FILE *fpdst2
= fopen(signaturefile
, "w");
139 if (fpdst2
== NULL
) {
140 fprintf(stderr
, "Not able to open the signature file for writing, aborting");
143 for (k
= 0; k
< skip_length
; k
++) {
144 fprintf(fpdst2
, "%c", data
[k
]);
151 int size
= st
.st_size
;
152 if(size
< skip_offset
+skip_length
){
153 fprintf(stderr
, "offset+length cannot be less than the file size\n");
157 static char buffer
[65];
158 sha256_file(filename
, buffer
, skip_offset
, skip_length
);
159 printf("%s\n", buffer
);
162 FILE *f
= fopen(digestfile
, "w");
164 printf("Error opening digestfile\n");
167 fprintf(f
, "%s", buffer
);
169 if (! g_file_test(digestfile
, G_FILE_TEST_IS_REGULAR
)) {
170 printf("Error writing digestfile\n");
175 gchar
*gpg2_path
= g_find_program_in_path ("gpg2");
176 sprintf (command
, "%s --verify %s %s", gpg2_path
, signaturefile
, digestfile
);
177 fprintf (stderr
, "%s\n", command
);
178 FILE *fp
= popen(command
, "r");
180 fprintf(stderr
, "gpg2 command did not succeed");
181 int exitcode
= WEXITSTATUS(pclose(fp
));
183 unlink(signaturefile
);