xhost + # Workaround for: QXcbConnection: Could not connect to display :0
[appimagekit.git] / validate.c
blob625a839c3f7954e6309e4f6502ef68a2c2ad255d
1 /*
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
3 */
5 #include <glib.h>
6 #include <glib/gprintf.h>
7 #include <stdio.h>
8 #include <string.h>
9 #include <errno.h>
10 #include <openssl/sha.h>
11 #include <stdlib.h>
12 #include <sys/stat.h>
13 #include <linux/limits.h>
14 #include <unistd.h>
15 #include <libgen.h>
16 #include <elf.h>
17 #include <fcntl.h>
18 #include <sys/mman.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");
29 if(!file) return(1);
30 byte hash[SHA256_DIGEST_LENGTH];
31 SHA256_CTX sha256;
32 SHA256_Init(&sha256);
33 const int bufSize = 1024*1024;
34 byte *buffer = malloc(bufSize);
35 int bytesRead = 0;
36 if(!buffer) {
37 fclose(file);
38 return ENOMEM;
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);
48 } else {
49 int stillToRead = skip_offset-bytesRead;
50 // printf("Initial stillToRead: %i\n", stillToRead);
51 int readThisTime;
53 if(stillToRead>bufSize){
54 readThisTime = bufSize;
55 } else {
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;
70 } else {
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 */
79 int i = 0;
80 for(i = 0; i < skip_length; i++) {
81 SHA256_Update(&sha256, "\0", 1);
82 totalBytesRead += 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;
102 fclose(file);
104 return 0;
107 int main(int argc,char **argv) {
108 if(argc < 2){
109 fprintf(stderr, "Usage: %s Signed.AppImage\n", argv[0]);
110 exit(1);
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);
121 } else {
122 fprintf(stderr, "ELF section %s not found, is the file signed?\n", segment_name);
123 exit(1);
126 char *digestfile;
127 digestfile = g_strconcat("/tmp/", basename(g_strconcat(filename, ".digest", NULL)), NULL);
128 char *signaturefile;
129 signaturefile = g_strconcat("/tmp/", basename(g_strconcat(filename, ".sig", NULL)), NULL);
131 uint8_t *data;
132 unsigned long k;
133 int fd = open(filename, O_RDONLY);
134 data = mmap(NULL, lseek(fd, 0, SEEK_END), PROT_READ, MAP_SHARED, fd, 0);
135 close(fd);
136 FILE *fpdst2 = fopen(signaturefile, "w");
137 if (fpdst2 == NULL) {
138 fprintf(stderr, "Not able to open the signature file for writing, aborting");
139 exit(1);
141 for (k = skip_offset; k < skip_offset + skip_length; k++) {
142 fprintf(fpdst2, "%c", data[k]);
144 fclose(fpdst2);
146 struct stat st;
147 stat(filename, &st);
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");
151 exit(1);
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");
160 if (f == NULL){
161 printf("Error opening digestfile\n");
162 exit(1);
164 fprintf(f, "%s", buffer);
165 fclose(f);
166 if (! g_file_test(digestfile, G_FILE_TEST_IS_REGULAR)) {
167 printf("Error writing digestfile\n");
168 exit(1);
171 char command[1024];
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");
176 if (fp == NULL)
177 fprintf(stderr, "gpg2 command did not succeed");
178 int exitcode = WEXITSTATUS(pclose(fp));
179 unlink(digestfile);
180 unlink(signaturefile);
181 return exitcode;