static void inject_signature(const char *xar_path, const char *sig_path) { // since there is no API to insert a signature other than during signingCallback time, we have to // inject it by editing the raw file int buffer_size = 1024; void *buffer = malloc(buffer_size); FILE *sig, *xar; off_t signedDataOffset; xar_t x; int i; printf("inject_signature(%s, %s)",xar_path,sig_path); // open xar via the API first to determine the signature offset x = xar_open(xar_path, READ); if ( x == NULL ) { fprintf(stderr, "Could not open xar archive %s to get signature offset!\n", xar_path); exit(1); } signedDataOffset = get_sig_offset(x); xar_close(x); // then re-open xar and signature files raw... sig = fopen(sig_path, "r"); if (!sig) { fprintf(stderr, "Could not open %s for reading signature!\n", sig_path); exit(1); } xar = fopen(xar_path, "r+"); if (!xar) { fprintf(stderr, "Could not open xar archive %s for injecting signature!\n", xar_path); exit(1); } // ...and inject the signature fseek(xar, signedDataOffset, SEEK_SET); do { i = fread(buffer, 1, buffer_size, sig); if (ferror(sig)) { fprintf(stderr, "Failed to read signature from %s!\n", sig_path); exit(1); } fwrite(buffer, 1, i, xar); } while (!feof(sig)); fclose(sig); fclose(xar); free(buffer); }
int check_resume_block(FILE *dev, off_t offset) { char buf[11] = {0,}; off_t location = offset + get_sig_offset(0); if (fseek(dev, location, SEEK_SET) < 0) return -1; if (fread(buf, sizeof (char), 10, dev) != 10) return -1; if (!strncmp(buf, "S1SUSPEND", 9) || !strncmp(buf, "ULSUSPEND", 9)) return 1; return 0; }
int clear_resume_block(FILE *dev, off_t offset) { char buf[21] = {0,}; off_t location = offset + get_sig_offset(1); if (fseek(dev, location, SEEK_SET) < 0) return -1; if (fread(buf, sizeof (char), 20, dev) != 20) return -1; if (fseek(dev, location, SEEK_SET) < 0) return -1; memmove(buf+10, buf, 10); memset(buf, '\0', 10); if (fwrite(buf, sizeof (char), 20, dev) != 20) return -1; return 0; }
static int extract_sig_offset(xar_t x, const char *filename) { off_t signedDataOffset; FILE *file; int i; // get offset signedDataOffset = get_sig_offset(x); // and save it to file file = fopen(filename, "w"); if (!file) { fprintf(stderr, "Could not open %s for saving signature offset!\n", filename); return 1; } i = fprintf(file, "%lli\n", signedDataOffset); if (i < 0) { fprintf(stderr, "Failed to write signature offset to %s (fprintf() returned %i)!\n", filename, i); return 1; } fclose(file); return 0; }