Skip to content

Commit

Permalink
query properties (thx @DanyL)
Browse files Browse the repository at this point in the history
  • Loading branch information
xerub committed Oct 27, 2020
1 parent c84a92c commit be2e7dd
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 1 deletion.
20 changes: 19 additions & 1 deletion img4.c
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,7 @@ usage(const char *argv0)
printf(" -g <file> write keybag to <file>\n");
printf(" -m <file> write ticket to <file>\n");
printf(" -c <info> check signature with <info>\n");
printf(" -q <prop> query property\n");
printf(" -f check hash against manifest\n");
printf(" -n print nonce\n");
printf(" -b print kbags\n");
Expand Down Expand Up @@ -404,6 +405,7 @@ main(int argc, char **argv)
const char *ename = NULL;
const char *gname = NULL;
const char *mname = NULL;
const char *query = NULL;
char *cinfo = NULL;
int get_nonce = 0;
int get_kbags = 0;
Expand Down Expand Up @@ -484,6 +486,8 @@ main(int argc, char **argv)
if (argc >= 2) { mname = *++argv; argc--; continue; }
case 'c':
if (argc >= 2) { cinfo = *++argv; argc--; continue; }
case 'q':
if (argc >= 2) { query = *++argv; argc--; continue; }
case 'T':
if (argc >= 2) { set_type = *++argv; argc--; continue; }
case 'P':
Expand Down Expand Up @@ -569,7 +573,7 @@ main(int argc, char **argv)
fd->close(fd);
return -1;
}
if (!get_nonce && !get_kbags && !get_version) {
if (!get_nonce && !get_kbags && !get_version && !query) {
printf("%c%c%c%c\n", FOURCC(type));
}

Expand Down Expand Up @@ -609,6 +613,20 @@ main(int argc, char **argv)
}
rc |= rv;
}
if (query) {
unsigned char result[256];
unsigned int i, len = sizeof(result);
rv = fd->ioctl(fd, IOCTL_IMG4_QUERY_PROP, query, result, &len);
if (rv) {
fprintf(stderr, "[e] query failed\n");
} else {
for (i = 0; i < len; i++) {
printf("%02x", result[i]);
}
printf("\n");
}
rc |= rv;
}
if (get_nonce) {
uint64_t nonce = 0;
rv = fd->ioctl(fd, IOCTL_IMG4_GET_NONCE, &nonce);
Expand Down
1 change: 1 addition & 0 deletions libvfs/vfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ struct file_ops {
#define IOCTL_IMG4_SET_KEYBAG2 69 /* (unsigned char[48], unsigned char[48]) */
#define IOCTL_IMG4_GET_VERSION 70 /* (void **, size_t *) */
#define IOCTL_IMG4_SET_VERSION 71 /* (void *, size_t) */
#define IOCTL_IMG4_QUERY_PROP 80 /* (const char *, unsigned char *, unsigned int *) */
#define IOCTL_IMG4_EVAL_TRUST 90 /* (void *) */

#define FLAG_IMG4_SKIP_DECOMPRESSION (1 << 0)
Expand Down
100 changes: 100 additions & 0 deletions libvfs/vfs_img4.c
Original file line number Diff line number Diff line change
Expand Up @@ -1437,6 +1437,74 @@ image4_validate_property_callback(DERTag tag, DERItem *b, DictType what, void *c
return 0;
}

static int
query_property_callback(DERTag tag, DERItem *b, DictType what, void *ctx)
{
int rv;
DERMonster *tmp = (DERMonster *)ctx;
if ((unsigned int)tag != tmp->tag) {
return 0;
}
// thx @DanyL
switch ((unsigned int)tag) {
case 'AMNM':
case 'CPRO':
case 'CSEC':
case 'DPRO':
case 'EKEY':
case 'EPRO':
case 'ESEC': {
bool value;
rv = Img4DecodeGetPropertyBoolean(b, tag, &value);
if (rv) {
return rv;
}
if (tmp->item.length < sizeof(bool)) {
return -1;
}
tmp->item.length = sizeof(bool);
*(bool *)tmp->item.data = value;
tmp->tag = 0;
break;
}
case 'BORD':
case 'CEPO':
case 'CHIP':
case 'ECID':
case 'SDOM': {
uint64_t value;
rv = Img4DecodeGetPropertyInteger64(b, tag, &value);
if (rv) {
return rv;
}
if (tmp->item.length < sizeof(uint64_t)) {
return -1;
}
tmp->item.length = sizeof(uint64_t);
*(uint64_t *)tmp->item.data = value;
tmp->tag = 0;
break;
}
case 'BNCH':
case 'DGST': {
DERByte *data;
DERSize length;
rv = Img4DecodeGetPropertyData(b, tag, &data, &length);
if (rv) {
return rv;
}
if (tmp->item.length < length) {
return -1;
}
tmp->item.length = length;
memmove(tmp->item.data, data, length);
tmp->tag = 0;
break;
}
}
return 0;
}

static int
hash_property_callback(DERTag tag, DERItem *b, DictType what, void *ctx)
{
Expand Down Expand Up @@ -2263,6 +2331,38 @@ img4_ioctl(FHANDLE fd, unsigned long req, ...)
ctx->dirty = 1;
break;
}
case IOCTL_IMG4_QUERY_PROP: {
const char *prop = va_arg(ap, char *);
unsigned char *out = va_arg(ap, unsigned char *);
unsigned int *len = va_arg(ap, unsigned int *);
unsigned int fourcc;
TheImg4Manifest m;
DERMonster tmp;
for (fourcc = 0; *prop; prop++) {
fourcc = (fourcc << 8) | *prop;
}
if (!fourcc) {
rv = -1;
break;
}
rv = DERImg4DecodeManifest(&ctx->manifest, &m);
if (rv) {
break;
}
tmp.item.data = out;
tmp.item.length = *len;
tmp.tag = fourcc;
rv = walkman(&m, ctx->type, query_property_callback, &tmp);
if (rv) {
break;
}
if (tmp.tag) {
rv = -1;
break;
}
*len = tmp.item.length;
break;
}
case IOCTL_ENC_SET_NOENC: if (fd->flags == O_RDONLY) break; else {
FHANDLE pfd = ctx->pfd;
pfd->ioctl(pfd, req); /* may fail if enc is just a pass-through */
Expand Down

0 comments on commit be2e7dd

Please sign in to comment.