diff options
| author | 2016-12-22 14:40:46 +0100 | |
|---|---|---|
| committer | 2016-12-22 14:40:46 +0100 | |
| commit | a80ba9363b4dc0ea1bcdad152cf2cdc974636ad6 (patch) | |
| tree | d3262371ca40a5a0dbddae521c080f6d295d4c40 /tools | |
| parent | 2b8313181fb52cecd1db20f11c0da0c2c169050a (diff) | |
| download | libimobiledevice-a80ba9363b4dc0ea1bcdad152cf2cdc974636ad6.tar.gz libimobiledevice-a80ba9363b4dc0ea1bcdad152cf2cdc974636ad6.tar.bz2 | |
ideviceprovision: Fix ASN1 parsing for large provisioning profiles
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/ideviceprovision.c | 47 |
1 files changed, 35 insertions, 12 deletions
diff --git a/tools/ideviceprovision.c b/tools/ideviceprovision.c index 26ec418..db00702 100644 --- a/tools/ideviceprovision.c +++ b/tools/ideviceprovision.c | |||
| @@ -87,30 +87,47 @@ enum { | |||
| 87 | 87 | ||
| 88 | static void asn1_next_item(unsigned char** p) | 88 | static void asn1_next_item(unsigned char** p) |
| 89 | { | 89 | { |
| 90 | if (*(*p+1) & 0x80) { | 90 | char bsize = *(*p+1); |
| 91 | *p += 4; | 91 | if (bsize & 0x80) { |
| 92 | *p += 2 + (bsize & 0xF); | ||
| 92 | } else { | 93 | } else { |
| 93 | *p += 3; | 94 | *p += 3; |
| 94 | } | 95 | } |
| 95 | } | 96 | } |
| 96 | 97 | ||
| 97 | static int asn1_item_get_size(unsigned char* p) | 98 | static size_t asn1_item_get_size(unsigned char* p) |
| 98 | { | 99 | { |
| 99 | int res = 0; | 100 | size_t res = 0; |
| 100 | if (*(p+1) & 0x80) { | 101 | char bsize = *(p+1); |
| 102 | if (bsize & 0x80) { | ||
| 101 | uint16_t ws = 0; | 103 | uint16_t ws = 0; |
| 102 | memcpy(&ws, p+2, 2); | 104 | uint32_t ds = 0; |
| 103 | ws = ntohs(ws); | 105 | switch (bsize & 0xF) { |
| 104 | res = ws; | 106 | case 2: |
| 107 | ws = *(uint16_t*)(p+2); | ||
| 108 | res = ntohs(ws); | ||
| 109 | break; | ||
| 110 | case 3: | ||
| 111 | ds = *(uint32_t*)(p+2); | ||
| 112 | res = ntohl(ds) >> 8; | ||
| 113 | break; | ||
| 114 | case 4: | ||
| 115 | ds = *(uint32_t*)(p+2); | ||
| 116 | res = ntohl(ds); | ||
| 117 | break; | ||
| 118 | default: | ||
| 119 | fprintf(stderr, "ERROR: Invalid or unimplemented byte size %d\n", bsize & 0xF); | ||
| 120 | break; | ||
| 121 | } | ||
| 105 | } else { | 122 | } else { |
| 106 | res = (int) *(p+1); | 123 | res = (int)bsize; |
| 107 | } | 124 | } |
| 108 | return res; | 125 | return res; |
| 109 | } | 126 | } |
| 110 | 127 | ||
| 111 | static void asn1_skip_item(unsigned char** p) | 128 | static void asn1_skip_item(unsigned char** p) |
| 112 | { | 129 | { |
| 113 | int sz = asn1_item_get_size(*p); | 130 | size_t sz = asn1_item_get_size(*p); |
| 114 | *p += 2; | 131 | *p += 2; |
| 115 | *p += sz; | 132 | *p += sz; |
| 116 | } | 133 | } |
| @@ -136,8 +153,14 @@ static plist_t profile_get_embedded_plist(plist_t profile) | |||
| 136 | fprintf(stderr, "%s: unexpected profile data (0)\n", __func__); | 153 | fprintf(stderr, "%s: unexpected profile data (0)\n", __func__); |
| 137 | return NULL; | 154 | return NULL; |
| 138 | } | 155 | } |
| 139 | uint16_t slen = asn1_item_get_size(pp); | 156 | size_t slen = asn1_item_get_size(pp); |
| 140 | if (slen+4 != (uint16_t)blen) { | 157 | char bsize = *(pp+1); |
| 158 | if (bsize & 0x80) { | ||
| 159 | slen += 2 + bsize & 0xF; | ||
| 160 | } else { | ||
| 161 | slen += 3; | ||
| 162 | } | ||
| 163 | if (slen != blen) { | ||
| 141 | free(bbuf); | 164 | free(bbuf); |
| 142 | fprintf(stderr, "%s: unexpected profile data (1)\n", __func__); | 165 | fprintf(stderr, "%s: unexpected profile data (1)\n", __func__); |
| 143 | return NULL; | 166 | return NULL; |
