2 cc -o validate ../getsection.c ../validate.c -lssl -lcrypto $(pkg-config --cflags glib-2.0) -I/usr/lib/x86_64-linux-gnu/glib-2.0/include
6 #include <glib/gprintf.h>
10 #include <openssl/sha.h>
13 #include <linux/limits.h>
20 #include "getsection.h"
22 typedef unsigned char byte
;
24 char segment_name
[] = ".sha256_sig";
26 int sha256_file(char *path
, char outputBuffer
[65], int skip_offset
, int skip_length
)
28 FILE *file
= fopen(path
, "rb");
30 byte hash
[SHA256_DIGEST_LENGTH
];
33 const int bufSize
= 1024*1024;
34 byte
*buffer
= malloc(bufSize
);
41 int totalBytesRead
= 0;
42 if(skip_offset
<= bufSize
){
43 bytesRead
= fread(buffer
, 1, skip_offset
, file
);
44 totalBytesRead
+= bytesRead
;
45 // printf("totalBytesRead: %i\n", totalBytesRead);
46 // printf("bytesRead: %i\n", bytesRead);
47 SHA256_Update(&sha256
, buffer
, bytesRead
);
49 int stillToRead
= skip_offset
-bytesRead
;
50 // printf("Initial stillToRead: %i\n", stillToRead);
53 if(stillToRead
>bufSize
){
54 readThisTime
= bufSize
;
56 readThisTime
= stillToRead
;
58 while((bytesRead
= fread(buffer
, 1, readThisTime
, file
)))
60 totalBytesRead
+= bytesRead
;
61 // printf("totalBytesRead: %i\n", totalBytesRead);
62 // printf("readThisTime: %i\n", readThisTime);
63 // printf("bytesRead: %i\n", bytesRead);
64 SHA256_Update(&sha256
, buffer
, bytesRead
);
65 stillToRead
= skip_offset
-totalBytesRead
;
66 // printf("stillToRead: %i\n", stillToRead);
68 if(stillToRead
>bufSize
){
69 readThisTime
= bufSize
;
71 readThisTime
= stillToRead
;
76 fseek(file
, skip_offset
+skip_length
, SEEK_SET
);
78 /* Instead of the skipped area, calculate the sha256 of the same amount if 0x00s */
80 for(i
= 0; i
< skip_length
; i
++) {
81 SHA256_Update(&sha256
, "\0", 1);
85 while((bytesRead
= fread(buffer
, 1, bufSize
, file
)))
87 totalBytesRead
+= bytesRead
;
88 // printf("totalBytesRead: %i\n", totalBytesRead);
89 // printf("bytesRead: %i\n", bytesRead);
90 SHA256_Update(&sha256
, buffer
, bytesRead
);
92 SHA256_Final(hash
, &sha256
);
94 // fprintf(stderr, "totalBytesRead: %i\n", totalBytesRead);
96 for(i
= 0; i
< SHA256_DIGEST_LENGTH
; i
++)
98 sprintf(outputBuffer
+ (i
* 2), "%02x", hash
[i
]);
100 outputBuffer
[64] = 0;
107 int main(int argc
,char **argv
) {
109 fprintf(stderr
, "Usage: %s Signed.AppImage\n", argv
[0]);
113 char *filename
= argv
[1];
115 unsigned long skip_offset
= 0;
116 unsigned long skip_length
= 0;
118 get_elf_section_offset_and_lenghth(filename
, ".sha256_sig", &skip_offset
, &skip_length
);
119 if(skip_length
> 0) {
120 fprintf(stderr
, "Skipping ELF section %s with offset %lu, length %lu\n", segment_name
, skip_offset
, skip_length
);
122 fprintf(stderr
, "ELF section %s not found, is the file signed?\n", segment_name
);
127 digestfile
= g_strconcat("/tmp/", basename(g_strconcat(filename
, ".digest", NULL
)), NULL
);
129 signaturefile
= g_strconcat("/tmp/", basename(g_strconcat(filename
, ".sig", NULL
)), NULL
);
133 int fd
= open(filename
, O_RDONLY
);
134 data
= mmap(NULL
, lseek(fd
, 0, SEEK_END
), PROT_READ
, MAP_SHARED
, fd
, 0);
136 FILE *fpdst2
= fopen(signaturefile
, "w");
137 if (fpdst2
== NULL
) {
138 fprintf(stderr
, "Not able to open the signature file for writing, aborting");
141 for (k
= skip_offset
; k
< skip_offset
+ skip_length
; k
++) {
142 fprintf(fpdst2
, "%c", data
[k
]);
148 int size
= st
.st_size
;
149 if(size
< skip_offset
+skip_length
){
150 fprintf(stderr
, "offset+length cannot be less than the file size\n");
154 static char buffer
[65];
155 sha256_file(filename
, buffer
, skip_offset
, skip_length
);
156 printf("%s\n", buffer
);
159 FILE *f
= fopen(digestfile
, "w");
161 printf("Error opening digestfile\n");
164 fprintf(f
, "%s", buffer
);
166 if (! g_file_test(digestfile
, G_FILE_TEST_IS_REGULAR
)) {
167 printf("Error writing digestfile\n");
172 gchar
*gpg2_path
= g_find_program_in_path ("gpg2");
173 sprintf (command
, "%s --verify %s %s", gpg2_path
, signaturefile
, digestfile
);
174 fprintf (stderr
, "%s\n", command
);
175 FILE *fp
= popen(command
, "r");
177 fprintf(stderr
, "gpg2 command did not succeed");
178 int exitcode
= WEXITSTATUS(pclose(fp
));
180 unlink(signaturefile
);