libextractor

GNU libextractor
Log | Files | Refs | Submodules | README | LICENSE

apk_extractor.c (55581B)


      1 /*
      2      This file is part of libextractor.
      3      Copyright (C) 2026 Vidyut Samanta and Christian Grothoff
      4 
      5      libextractor is free software; you can redistribute it and/or modify
      6      it under the terms of the GNU General Public License as published
      7      by the Free Software Foundation; either version 3, or (at your
      8      option) any later version.
      9 
     10      libextractor is distributed in the hope that it will be useful, but
     11      WITHOUT ANY WARRANTY; without even the implied warranty of
     12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13      General Public License for more details.
     14 
     15      You should have received a copy of the GNU General Public License
     16      along with libextractor; see the file COPYING.  If not, write to the
     17      Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     18      Boston, MA 02110-1301, USA.
     19  */
     20 /**
     21  * @file plugins/apk_extractor.c
     22  * @brief plugin to support Android packages and Java archives
     23  * @author Christian Grothoff
     24  *
     25  * An APK and a JAR are both ZIP files, and so are a docx, an ODF
     26  * document and any old archive, so the plugin identifies them by the
     27  * member they must contain -- `AndroidManifest.xml' for an APK,
     28  * `META-INF/MANIFEST.MF' for a JAR -- and returns without a word
     29  * otherwise.  An APK contains both, which is why the Android manifest
     30  * is looked for first.
     31  *
     32  * What is worth having here is what the package may do (its declared
     33  * permissions), what built it (the JDK or SDK version), and who signed
     34  * it (the subject of the signing certificate).
     35  *
     36  * References:
     37  * - AOSP frameworks/base/libs/androidfw/include/androidfw/ResourceTypes.h
     38  *   for the binary XML ("AXML") chunk format
     39  * - https://source.android.com/docs/security/features/apksigning for the
     40  *   APK Signing Block
     41  * - the JAR File Specification for `META-INF/MANIFEST.MF'
     42  * - RFC 5652 (PKCS#7/CMS) and RFC 5280 for the signature block
     43  */
     44 #include "platform.h"
     45 #include "extractor.h"
     46 #include "forensics.h"
     47 #include "unzip.h"
     48 
     49 
     50 /**
     51  * Name we report our meta data under.
     52  */
     53 #define PLUGIN_NAME "apk"
     54 
     55 /**
     56  * Never read more than this from `AndroidManifest.xml'.  Real ones are
     57  * a few tens of kilobytes even for very large applications.
     58  */
     59 #define MAX_AXML (512 * 1024)
     60 
     61 /**
     62  * Never read more than this from `META-INF/MANIFEST.MF'.
     63  */
     64 #define MAX_MANIFEST (256 * 1024)
     65 
     66 /**
     67  * Never read more than this from a `META-INF/*.RSA' signature block.
     68  */
     69 #define MAX_PKCS7 (256 * 1024)
     70 
     71 /**
     72  * Never read more than this of the APK Signing Block.
     73  */
     74 #define MAX_SIG_BLOCK (64 * 1024)
     75 
     76 /**
     77  * Upper bound on the number of ZIP members we walk.  The end of central
     78  * directory record counts entries in 16 bits, so this cannot be reached
     79  * by a well-formed archive.
     80  */
     81 #define MAX_MEMBERS 65535
     82 
     83 /**
     84  * Upper bound on the number of chunks and elements we walk in the
     85  * binary XML.
     86  */
     87 #define MAX_CHUNKS 65536
     88 
     89 /**
     90  * Upper bound on the number of strings in an AXML string pool.
     91  */
     92 #define MAX_POOL_STRINGS 200000
     93 
     94 /**
     95  * Upper bound on the nesting depth we follow when walking DER.
     96  */
     97 #define MAX_DER_DEPTH 16
     98 
     99 /* AXML chunk types, from ResourceTypes.h */
    100 #define RES_XML_TYPE               0x0003
    101 #define RES_STRING_POOL_TYPE       0x0001
    102 #define RES_XML_START_ELEMENT_TYPE 0x0102
    103 
    104 /* Res_value data types */
    105 #define TYPE_STRING      0x03
    106 #define TYPE_INT_DEC     0x10
    107 #define TYPE_INT_HEX     0x11
    108 #define TYPE_INT_BOOLEAN 0x12
    109 
    110 /* APK Signing Block pair identifiers */
    111 #define APK_SIG_SCHEME_V2   0x7109871AU
    112 #define APK_SIG_SCHEME_V3   0xF05368C0U
    113 #define APK_SIG_SCHEME_V31  0x1B93AD61U
    114 
    115 
    116 /**
    117  * A parsed AXML string pool.
    118  */
    119 struct StringPool
    120 {
    121   /**
    122    * Table of @e count 32 bit offsets into @e data.
    123    */
    124   const unsigned char *offsets;
    125 
    126   /**
    127    * The string data itself.
    128    */
    129   const unsigned char *data;
    130 
    131   /**
    132    * Number of bytes in @e data.
    133    */
    134   size_t data_len;
    135 
    136   /**
    137    * Number of strings in the pool.
    138    */
    139   uint32_t count;
    140 
    141   /**
    142    * True if the strings are UTF-8, false if they are UTF-16LE.
    143    */
    144   int utf8;
    145 };
    146 
    147 
    148 /**
    149  * What we learned from walking the ZIP central directory.
    150  */
    151 struct ArchiveFacts
    152 {
    153   /**
    154    * Base name of the `META-INF/<alias>.RSA' (or .DSA, .EC) member,
    155    * which is conventionally the signer's key alias.
    156    */
    157   char sig_alias[128];
    158 
    159   /**
    160    * Full member name of the signature block, empty if unsigned.
    161    */
    162   char sig_member[256];
    163 
    164   /**
    165    * Distinct ABI directory names seen under `lib/'.
    166    */
    167   char abis[8][32];
    168 
    169   /**
    170    * Number of entries used in @e abis.
    171    */
    172   unsigned int num_abis;
    173 
    174   /**
    175    * Number of `classes*.dex' members.
    176    */
    177   unsigned int num_dex;
    178 
    179   /**
    180    * Total number of members.
    181    */
    182   unsigned int num_members;
    183 };
    184 
    185 
    186 /**
    187  * Find @a needle in @a hay.  `memmem()' is a GNU extension and this only
    188  * ever runs over buffers of a few tens of kilobytes.
    189  *
    190  * @param hay buffer to search
    191  * @param hlen number of bytes in @a hay
    192  * @param needle bytes to look for
    193  * @param nlen number of bytes in @a needle
    194  * @return pointer into @a hay, NULL if @a needle does not occur
    195  */
    196 static const unsigned char *
    197 mem_find (const unsigned char *hay,
    198           size_t hlen,
    199           const char *needle,
    200           size_t nlen)
    201 {
    202   if ( (0 == nlen) ||
    203        (nlen > hlen) )
    204     return NULL;
    205   for (size_t i = 0; i + nlen <= hlen; i++)
    206     if (0 == memcmp (&hay[i],
    207                      needle,
    208                      nlen))
    209       return &hay[i];
    210   return NULL;
    211 }
    212 
    213 
    214 /**
    215  * Read a whole member out of a ZIP archive.
    216  *
    217  * @param uf the archive
    218  * @param name member to read
    219  * @param cap never read more than this many bytes
    220  * @param[out] len number of bytes read
    221  * @return the member's contents with a NUL appended, NULL on error;
    222  *         caller must free
    223  */
    224 static unsigned char *
    225 read_member (struct EXTRACTOR_UnzipFile *uf,
    226              const char *name,
    227              size_t cap,
    228              size_t *len)
    229 {
    230   struct EXTRACTOR_UnzipFileInfo fi;
    231   unsigned char *buf;
    232   size_t size;
    233   size_t got = 0;
    234 
    235   *len = 0;
    236   if (EXTRACTOR_UNZIP_OK !=
    237       EXTRACTOR_common_unzip_go_find_local_file (uf,
    238                                                  name,
    239                                                  2))
    240     return NULL;
    241   if (EXTRACTOR_UNZIP_OK !=
    242       EXTRACTOR_common_unzip_get_current_file_info (uf,
    243                                                     &fi,
    244                                                     NULL, 0,
    245                                                     NULL, 0,
    246                                                     NULL, 0))
    247     return NULL;
    248   size = (size_t) fi.uncompressed_size;
    249   if (0 == size)
    250     return NULL;
    251   if (size > cap)
    252     size = cap;
    253   if (NULL == (buf = malloc (size + 1)))
    254     return NULL;
    255   if (EXTRACTOR_UNZIP_OK !=
    256       EXTRACTOR_common_unzip_open_current_file (uf))
    257   {
    258     free (buf);
    259     return NULL;
    260   }
    261   while (got < size)
    262   {
    263     ssize_t ret;
    264 
    265     ret = EXTRACTOR_common_unzip_read_current_file (uf,
    266                                                     &buf[got],
    267                                                     size - got);
    268     if (0 >= ret)
    269       break;   /* error or end of member */
    270     if (((size_t) ret) > size - got)
    271       break;   /* cannot happen, but do not overrun if it does */
    272     got += (size_t) ret;
    273   }
    274   (void) EXTRACTOR_common_unzip_close_current_file (uf);
    275   if (0 == got)
    276   {
    277     free (buf);
    278     return NULL;
    279   }
    280   buf[got] = '\0';
    281   *len = got;
    282   return buf;
    283 }
    284 
    285 
    286 /* ------------------------------------------------------------------ */
    287 /* JAR manifest                                                        */
    288 /* ------------------------------------------------------------------ */
    289 
    290 
    291 /**
    292  * Report the value of one `META-INF/MANIFEST.MF' header, if it is one
    293  * we care about.
    294  *
    295  * @param ec extraction context
    296  * @param key header name, NUL-terminated
    297  * @param value header value, NUL-terminated and already unfolded
    298  * @return 1 if the caller should stop extracting, 0 to continue
    299  */
    300 static int
    301 emit_manifest_header (struct EXTRACTOR_ExtractContext *ec,
    302                       const char *key,
    303                       const char *value)
    304 {
    305   static const struct
    306   {
    307     const char *key;
    308     enum EXTRACTOR_MetaType type;
    309   } map[] = {
    310     { "Main-Class", EXTRACTOR_METATYPE_ENTRY_POINT },
    311     /* these three name the exact JDK the archive was built with */
    312     { "Created-By", EXTRACTOR_METATYPE_TOOLCHAIN },
    313     { "Build-Jdk", EXTRACTOR_METATYPE_TOOLCHAIN },
    314     { "Build-Jdk-Spec", EXTRACTOR_METATYPE_TOOLCHAIN },
    315     { "Class-Path", EXTRACTOR_METATYPE_LIBRARY_DEPENDENCY },
    316     { "Implementation-Title", EXTRACTOR_METATYPE_TITLE },
    317     { "Implementation-Version", EXTRACTOR_METATYPE_SOFTWARE_VERSION },
    318     { "Implementation-Vendor", EXTRACTOR_METATYPE_VENDOR },
    319     { "Implementation-URL", EXTRACTOR_METATYPE_URL },
    320     { "Specification-Title", EXTRACTOR_METATYPE_SUBJECT },
    321     { "Specification-Version", EXTRACTOR_METATYPE_FORMAT_VERSION },
    322     { "Specification-Vendor", EXTRACTOR_METATYPE_ORGANIZATION },
    323     /* OSGi bundle headers */
    324     { "Bundle-SymbolicName", EXTRACTOR_METATYPE_APPLICATION_ID },
    325     { "Bundle-Name", EXTRACTOR_METATYPE_PRODUCT_NAME },
    326     { "Bundle-Version", EXTRACTOR_METATYPE_PACKAGE_VERSION },
    327     { "Bundle-Vendor", EXTRACTOR_METATYPE_VENDOR },
    328     { "Bundle-Description", EXTRACTOR_METATYPE_DESCRIPTION },
    329     { "Bundle-License", EXTRACTOR_METATYPE_LICENSE },
    330     { "Bundle-RequiredExecutionEnvironment",
    331       EXTRACTOR_METATYPE_MINIMUM_OS_VERSION },
    332     { "Import-Package", EXTRACTOR_METATYPE_LIBRARY_DEPENDENCY },
    333     { NULL, EXTRACTOR_METATYPE_RESERVED }
    334   };
    335 
    336   for (unsigned int i = 0; NULL != map[i].key; i++)
    337     if (0 == strcasecmp (key,
    338                          map[i].key))
    339       return EXTRACTOR_forensic_emit_text_ (ec,
    340                                             PLUGIN_NAME,
    341                                             map[i].type,
    342                                             value,
    343                                             strlen (value));
    344   return 0;
    345 }
    346 
    347 
    348 /**
    349  * Walk the main section of a `META-INF/MANIFEST.MF'.
    350  *
    351  * The format is `Key: Value' with CRLF line breaks, and no line may
    352  * exceed 72 bytes, so long values are broken across continuation lines
    353  * that begin with a single space which is not part of the value.  Only
    354  * the main section (everything before the first blank line) describes
    355  * the archive; what follows is one section per signed member.
    356  *
    357  * @param ec extraction context
    358  * @param data the manifest
    359  * @param len number of bytes in @a data
    360  * @return 1 if the caller should stop extracting, 0 to continue
    361  */
    362 static int
    363 parse_jar_manifest (struct EXTRACTOR_ExtractContext *ec,
    364                     const char *data,
    365                     size_t len)
    366 {
    367   char key[128];
    368   char value[EXTRACTOR_FORENSIC_MAX_STRING];
    369   size_t pos = 0;
    370   size_t klen = 0;
    371   size_t vlen = 0;
    372   unsigned int headers = 0;
    373 
    374   key[0] = '\0';
    375   while ( (pos < len) &&
    376           (headers < 256) )
    377   {
    378     const char *nl;
    379     const char *line;
    380     size_t line_len;
    381     const char *colon;
    382 
    383     nl = memchr (&data[pos],
    384                  '\n',
    385                  len - pos);
    386     line = &data[pos];
    387     line_len = (NULL == nl)
    388                ? len - pos
    389                : (size_t) (nl - line);
    390     pos += line_len + ((NULL == nl) ? 0 : 1);
    391     if ( (0 < line_len) &&
    392          ('\r' == line[line_len - 1]) )
    393       line_len--;
    394     if (0 == line_len)
    395       break;   /* end of the main section */
    396     if (' ' == line[0])
    397     {
    398       /* continuation of the previous header */
    399       size_t add = line_len - 1;
    400 
    401       if (0 == klen)
    402         continue;   /* continuation without a header; ignore */
    403       if (add > sizeof (value) - 1 - vlen)
    404         add = sizeof (value) - 1 - vlen;
    405       memcpy (&value[vlen],
    406               &line[1],
    407               add);
    408       vlen += add;
    409       value[vlen] = '\0';
    410       continue;
    411     }
    412     /* a new header starts, so the previous one is complete */
    413     if ( (0 != klen) &&
    414          (0 != emit_manifest_header (ec,
    415                                      key,
    416                                      value)) )
    417       return 1;
    418     klen = 0;
    419     vlen = 0;
    420     headers++;
    421     colon = memchr (line,
    422                     ':',
    423                     line_len);
    424     if (NULL == colon)
    425       continue;
    426     klen = (size_t) (colon - line);
    427     if (klen > sizeof (key) - 1)
    428       klen = sizeof (key) - 1;
    429     memcpy (key,
    430             line,
    431             klen);
    432     key[klen] = '\0';
    433     vlen = line_len - (size_t) (colon - line) - 1;
    434     if ( (0 < vlen) &&
    435          (' ' == colon[1]) )
    436     {
    437       colon++;
    438       vlen--;
    439     }
    440     if (vlen > sizeof (value) - 1)
    441       vlen = sizeof (value) - 1;
    442     memcpy (value,
    443             &colon[1],
    444             vlen);
    445     value[vlen] = '\0';
    446   }
    447   if ( (0 != klen) &&
    448        (0 != emit_manifest_header (ec,
    449                                    key,
    450                                    value)) )
    451     return 1;
    452   return 0;
    453 }
    454 
    455 
    456 /* ------------------------------------------------------------------ */
    457 /* PKCS#7 signature block                                              */
    458 /* ------------------------------------------------------------------ */
    459 
    460 
    461 /**
    462  * One DER tag-length-value triple.
    463  */
    464 struct Tlv
    465 {
    466   /**
    467    * The tag byte.
    468    */
    469   unsigned int tag;
    470 
    471   /**
    472    * Offset of the value within the enclosing buffer.
    473    */
    474   size_t start;
    475 
    476   /**
    477    * Number of bytes in the value.
    478    */
    479   size_t len;
    480 
    481   /**
    482    * Offset just past the value, i.e. where the next TLV begins.
    483    */
    484   size_t next;
    485 };
    486 
    487 
    488 /**
    489  * Decode the DER tag-length-value triple at @a pos.
    490  *
    491  * Only the definite-length, low-tag-number form is accepted; a
    492  * certificate that needs anything else is not one we are going to
    493  * understand anyway.
    494  *
    495  * @param buf the buffer
    496  * @param end offset just past the region the TLV must fit in
    497  * @param pos offset of the tag byte
    498  * @param[out] tlv where to store the result
    499  * @return 1 on success, 0 if the encoding is malformed or truncated
    500  */
    501 static int
    502 der_read (const unsigned char *buf,
    503           size_t end,
    504           size_t pos,
    505           struct Tlv *tlv)
    506 {
    507   uint64_t len;
    508   size_t p = pos;
    509 
    510   if (p + 2 > end)
    511     return 0;
    512   tlv->tag = buf[p];
    513   if (0x1F == (tlv->tag & 0x1F))
    514     return 0;   /* high tag number form */
    515   p++;
    516   if (buf[p] < 0x80)
    517   {
    518     len = buf[p];
    519     p++;
    520   }
    521   else
    522   {
    523     unsigned int n = buf[p] & 0x7F;
    524 
    525     if ( (0 == n) ||
    526          (n > 4) )
    527       return 0;   /* indefinite length, or longer than we will ever want */
    528     p++;
    529     if (p + n > end)
    530       return 0;
    531     len = 0;
    532     for (unsigned int i = 0; i < n; i++)
    533       len = (len << 8) | buf[p + i];
    534     p += n;
    535   }
    536   if (len > (uint64_t) (end - p))
    537     return 0;
    538   tlv->start = p;
    539   tlv->len = (size_t) len;
    540   tlv->next = p + (size_t) len;
    541   return 1;
    542 }
    543 
    544 
    545 /**
    546  * Append the short name for an X.500 attribute type to @a out.
    547  *
    548  * Attribute types we do not have a name for are skipped rather than
    549  * spelled as an OID: a distinguished name that uses one is not one a
    550  * human is going to recognise either way.
    551  *
    552  * @param oid the OID's content bytes
    553  * @param len number of bytes in @a oid
    554  * @return the short name, NULL if unknown
    555  */
    556 static const char *
    557 x500_name (const unsigned char *oid,
    558            size_t len)
    559 {
    560   static const struct
    561   {
    562     const char *name;
    563     size_t len;
    564     const unsigned char oid[12];
    565   } known[] = {
    566     { "CN", 3, { 0x55, 0x04, 0x03 } },
    567     { "SN", 3, { 0x55, 0x04, 0x04 } },
    568     { "serialNumber", 3, { 0x55, 0x04, 0x05 } },
    569     { "C", 3, { 0x55, 0x04, 0x06 } },
    570     { "L", 3, { 0x55, 0x04, 0x07 } },
    571     { "ST", 3, { 0x55, 0x04, 0x08 } },
    572     { "STREET", 3, { 0x55, 0x04, 0x09 } },
    573     { "O", 3, { 0x55, 0x04, 0x0A } },
    574     { "OU", 3, { 0x55, 0x04, 0x0B } },
    575     { "T", 3, { 0x55, 0x04, 0x0C } },
    576     { "GN", 3, { 0x55, 0x04, 0x2A } },
    577     { "emailAddress", 9,
    578       { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01 } },
    579     { "DC", 10,
    580       { 0x09, 0x92, 0x26, 0x89, 0x93, 0xF2, 0x2C, 0x64, 0x01, 0x19 } },
    581     { "UID", 10,
    582       { 0x09, 0x92, 0x26, 0x89, 0x93, 0xF2, 0x2C, 0x64, 0x01, 0x01 } },
    583     { NULL, 0, { 0 } }
    584   };
    585 
    586   for (unsigned int i = 0; NULL != known[i].name; i++)
    587     if ( (known[i].len == len) &&
    588          (0 == memcmp (known[i].oid,
    589                        oid,
    590                        len)) )
    591       return known[i].name;
    592   return NULL;
    593 }
    594 
    595 
    596 /**
    597  * Render an X.501 `Name' as an RFC 4514 style distinguished name.
    598  *
    599  * The relative distinguished names are emitted in the order they appear
    600  * in the encoding, which is what `openssl x509 -subject' prints too.
    601  *
    602  * @param buf buffer holding the encoding
    603  * @param name the `Name' TLV (a SEQUENCE OF RelativeDistinguishedName)
    604  * @param[out] out where to write the result, NUL-terminated
    605  * @param outsz number of bytes available in @a out, at least 2
    606  * @return 1 on success, 0 if nothing could be rendered
    607  */
    608 static int
    609 der_render_name (const unsigned char *buf,
    610                  const struct Tlv *name,
    611                  char *out,
    612                  size_t outsz)
    613 {
    614   size_t o = 0;
    615   size_t pos = name->start;
    616   unsigned int rdns = 0;
    617 
    618   out[0] = '\0';
    619   while ( (pos < name->start + name->len) &&
    620           (rdns++ < 32) )
    621   {
    622     struct Tlv rdn;
    623     size_t apos;
    624 
    625     if (! der_read (buf,
    626                     name->start + name->len,
    627                     pos,
    628                     &rdn))
    629       break;
    630     pos = rdn.next;
    631     if (0x31 != rdn.tag)
    632       continue;   /* not a SET */
    633     apos = rdn.start;
    634     while (apos < rdn.start + rdn.len)
    635     {
    636       struct Tlv atv;
    637       struct Tlv oid;
    638       struct Tlv value;
    639       const char *label;
    640 
    641       if (! der_read (buf,
    642                       rdn.start + rdn.len,
    643                       apos,
    644                       &atv))
    645         break;
    646       apos = atv.next;
    647       if (0x30 != atv.tag)
    648         continue;
    649       if (! der_read (buf,
    650                       atv.start + atv.len,
    651                       atv.start,
    652                       &oid))
    653         continue;
    654       if (0x06 != oid.tag)
    655         continue;
    656       if (! der_read (buf,
    657                       atv.start + atv.len,
    658                       oid.next,
    659                       &value))
    660         continue;
    661       /* UTF8String, PrintableString, T61String, IA5String; BMPString
    662          and UniversalString are left out because they would need a
    663          conversion we would only ever exercise on broken input */
    664       if ( (0x0C != value.tag) &&
    665            (0x13 != value.tag) &&
    666            (0x14 != value.tag) &&
    667            (0x16 != value.tag) )
    668         continue;
    669       label = x500_name (&buf[oid.start],
    670                          oid.len);
    671       if (NULL == label)
    672         continue;
    673       if (0 != o)
    674       {
    675         if (o + 2 >= outsz)
    676           break;
    677         out[o++] = ',';
    678         out[o++] = ' ';
    679       }
    680       if (o + strlen (label) + 1 >= outsz)
    681         break;
    682       memcpy (&out[o],
    683               label,
    684               strlen (label));
    685       o += strlen (label);
    686       out[o++] = '=';
    687       for (size_t i = 0; i < value.len; i++)
    688       {
    689         unsigned char c = buf[value.start + i];
    690 
    691         if (o + 2 >= outsz)
    692           break;
    693         /* RFC 4514 escaping, so that a CN containing a comma cannot
    694            look like two relative distinguished names */
    695         if ( (',' == c) || ('+' == c) || ('"' == c) || ('\\' == c) ||
    696              ('<' == c) || ('>' == c) || (';' == c) )
    697           out[o++] = '\\';
    698         out[o++] = (char) c;
    699       }
    700     }
    701   }
    702   out[o] = '\0';
    703   return (0 != o);
    704 }
    705 
    706 
    707 /**
    708  * Pull the signer's distinguished name out of a PKCS#7 signature block.
    709  *
    710  * The certificates in a `META-INF/*.RSA' come in no particular order --
    711  * in a chain signed archive the certificate authority typically comes
    712  * first -- so the signer is identified the way RFC 5652 says: by
    713  * matching the SignerInfo's issuerAndSerialNumber against each
    714  * certificate's issuer and serial number.
    715  *
    716  * @param buf the DER encoding
    717  * @param len number of bytes in @a buf
    718  * @param[out] out where to write the distinguished name, NUL-terminated
    719  * @param outsz number of bytes available in @a out, at least 2
    720  * @return 1 on success, 0 if the block could not be understood
    721  */
    722 static int
    723 pkcs7_signer_dn (const unsigned char *buf,
    724                  size_t len,
    725                  char *out,
    726                  size_t outsz)
    727 {
    728   struct Tlv content_info;
    729   struct Tlv oid;
    730   struct Tlv explicit0;
    731   struct Tlv signed_data;
    732   struct Tlv tlv;
    733   struct Tlv certs;
    734   struct Tlv signer_infos;
    735   struct Tlv signer_issuer;
    736   struct Tlv signer_serial;
    737   size_t pos;
    738   size_t end;
    739   int have_signer = 0;
    740   int have_certs = 0;
    741   unsigned int fields = 0;
    742 
    743   out[0] = '\0';
    744   if (! der_read (buf, len, 0, &content_info))
    745     return 0;
    746   if (0x30 != content_info.tag)
    747     return 0;
    748   end = content_info.start + content_info.len;
    749   if (! der_read (buf, end, content_info.start, &oid))
    750     return 0;
    751   if (0x06 != oid.tag)
    752     return 0;
    753   if (! der_read (buf, end, oid.next, &explicit0))
    754     return 0;
    755   if (0xA0 != explicit0.tag)
    756     return 0;
    757   if (! der_read (buf,
    758                   explicit0.start + explicit0.len,
    759                   explicit0.start,
    760                   &signed_data))
    761     return 0;
    762   if (0x30 != signed_data.tag)
    763     return 0;
    764   /* SignedData ::= SEQUENCE { version, digestAlgorithms, contentInfo,
    765                                [0] certificates OPTIONAL,
    766                                [1] crls OPTIONAL, signerInfos }
    767      The first three fields have to be stepped over positionally:
    768      digestAlgorithms is a SET and so is signerInfos, so a search by tag
    769      would stop at the wrong one. */
    770   end = signed_data.start + signed_data.len;
    771   pos = signed_data.start;
    772   for (unsigned int i = 0; i < 3; i++)
    773   {
    774     if (! der_read (buf, end, pos, &tlv))
    775       return 0;
    776     pos = tlv.next;
    777   }
    778   memset (&signer_infos,
    779           0,
    780           sizeof (signer_infos));
    781   while ( (pos < end) &&
    782           (fields++ < MAX_DER_DEPTH) )
    783   {
    784     if (! der_read (buf, end, pos, &tlv))
    785       return 0;
    786     pos = tlv.next;
    787     if (0xA0 == tlv.tag)
    788     {
    789       certs = tlv;
    790       have_certs = 1;
    791     }
    792     else if (0x31 == tlv.tag)
    793     {
    794       signer_infos = tlv;
    795       break;
    796     }
    797   }
    798   if (! have_certs)
    799     return 0;
    800   /* SignerInfo ::= SEQUENCE { version, issuerAndSerialNumber, ... } */
    801   if (der_read (buf,
    802                 signer_infos.start + signer_infos.len,
    803                 signer_infos.start,
    804                 &tlv) &&
    805       (0x30 == tlv.tag))
    806   {
    807     struct Tlv version;
    808     struct Tlv ias;
    809 
    810     if (der_read (buf, tlv.start + tlv.len, tlv.start, &version) &&
    811         der_read (buf, tlv.start + tlv.len, version.next, &ias) &&
    812         (0x30 == ias.tag) &&
    813         der_read (buf, ias.start + ias.len, ias.start, &signer_issuer) &&
    814         der_read (buf, ias.start + ias.len, signer_issuer.next,
    815                   &signer_serial) &&
    816         (0x30 == signer_issuer.tag) &&
    817         (0x02 == signer_serial.tag))
    818       have_signer = 1;
    819   }
    820   /* walk the certificates and take the one the SignerInfo points at */
    821   pos = certs.start;
    822   end = certs.start + certs.len;
    823   for (unsigned int i = 0; (pos < end) && (i < 32); i++)
    824   {
    825     struct Tlv cert;
    826     struct Tlv tbs;
    827     struct Tlv field;
    828     struct Tlv serial;
    829     struct Tlv issuer;
    830     struct Tlv validity;
    831     struct Tlv subject;
    832 
    833     if (! der_read (buf, end, pos, &cert))
    834       break;
    835     pos = cert.next;
    836     if (0x30 != cert.tag)
    837       continue;
    838     if (! der_read (buf, cert.start + cert.len, cert.start, &tbs))
    839       continue;
    840     if (0x30 != tbs.tag)
    841       continue;
    842     /* TBSCertificate ::= SEQUENCE { [0] version DEFAULT v1,
    843          serialNumber, signature, issuer, validity, subject, ... } */
    844     if (! der_read (buf, tbs.start + tbs.len, tbs.start, &field))
    845       continue;
    846     if (0xA0 == field.tag)
    847     {
    848       if (! der_read (buf, tbs.start + tbs.len, field.next, &serial))
    849         continue;
    850     }
    851     else
    852     {
    853       serial = field;
    854     }
    855     if (0x02 != serial.tag)
    856       continue;
    857     if (! der_read (buf, tbs.start + tbs.len, serial.next, &field))
    858       continue;   /* signature algorithm */
    859     if (! der_read (buf, tbs.start + tbs.len, field.next, &issuer))
    860       continue;
    861     if (0x30 != issuer.tag)
    862       continue;
    863     if (! der_read (buf, tbs.start + tbs.len, issuer.next, &validity))
    864       continue;
    865     if (! der_read (buf, tbs.start + tbs.len, validity.next, &subject))
    866       continue;
    867     if (0x30 != subject.tag)
    868       continue;
    869     if (have_signer)
    870     {
    871       /* RFC 5652 identifies the signer's certificate by issuer name
    872          and serial number, so match on both */
    873       if ( (signer_serial.len != serial.len) ||
    874            (0 != memcmp (&buf[signer_serial.start],
    875                          &buf[serial.start],
    876                          serial.len)) )
    877         continue;
    878       if ( (signer_issuer.len != issuer.len) ||
    879            (0 != memcmp (&buf[signer_issuer.start],
    880                          &buf[issuer.start],
    881                          issuer.len)) )
    882         continue;
    883     }
    884     return der_render_name (buf,
    885                             &subject,
    886                             out,
    887                             outsz);
    888   }
    889   return 0;
    890 }
    891 
    892 
    893 /* ------------------------------------------------------------------ */
    894 /* binary XML                                                          */
    895 /* ------------------------------------------------------------------ */
    896 
    897 
    898 /**
    899  * Fetch string number @a idx out of an AXML string pool, converted to
    900  * UTF-8 and NUL-terminated.
    901  *
    902  * @param sp the pool
    903  * @param idx index of the string
    904  * @param[out] out where to write the string
    905  * @param outsz number of bytes available in @a out, at least 8
    906  * @return number of bytes written, 0 if the string could not be read
    907  */
    908 static size_t
    909 pool_string (const struct StringPool *sp,
    910              uint32_t idx,
    911              char *out,
    912              size_t outsz)
    913 {
    914   const unsigned char *p;
    915   size_t avail;
    916   uint32_t off;
    917 
    918   out[0] = '\0';
    919   if ( (NULL == sp->offsets) ||
    920        (idx >= sp->count) )
    921     return 0;
    922   off = EXTRACTOR_forensic_le32_ (&sp->offsets[4 * (size_t) idx]);
    923   if (((size_t) off) >= sp->data_len)
    924     return 0;
    925   p = &sp->data[off];
    926   avail = sp->data_len - off;
    927   if (sp->utf8)
    928   {
    929     size_t k = 0;
    930     size_t n8;
    931 
    932     /* two varints: the length in UTF-16 code units, then the length in
    933        bytes; a leading set high bit means the value takes two bytes */
    934     if (avail < 1)
    935       return 0;
    936     if (0 != (p[k] & 0x80))
    937     {
    938       if (avail < 2)
    939         return 0;
    940       k += 2;
    941     }
    942     else
    943     {
    944       k += 1;
    945     }
    946     if (avail < k + 1)
    947       return 0;
    948     if (0 != (p[k] & 0x80))
    949     {
    950       if (avail < k + 2)
    951         return 0;
    952       n8 = (size_t) (((((size_t) p[k]) & 0x7F) << 8) | p[k + 1]);
    953       k += 2;
    954     }
    955     else
    956     {
    957       n8 = p[k];
    958       k += 1;
    959     }
    960     if (n8 > avail - k)
    961       return 0;
    962     if (n8 > outsz - 1)
    963       n8 = outsz - 1;
    964     memcpy (out,
    965             &p[k],
    966             n8);
    967     out[n8] = '\0';
    968     if (! EXTRACTOR_forensic_utf8_valid_ (out,
    969                                           n8))
    970     {
    971       out[0] = '\0';
    972       return 0;
    973     }
    974     return n8;
    975   }
    976   {
    977     size_t k = 2;
    978     size_t n16;
    979     size_t o = 0;
    980 
    981     if (avail < 2)
    982       return 0;
    983     n16 = EXTRACTOR_forensic_le16_ (p);
    984     if (0 != (n16 & 0x8000))
    985     {
    986       if (avail < 4)
    987         return 0;
    988       n16 = (((n16 & 0x7FFF) << 16)
    989              | EXTRACTOR_forensic_le16_ (&p[2]));
    990       k = 4;
    991     }
    992     if (n16 > (avail - k) / 2)
    993       return 0;
    994     for (size_t i = 0; i < n16; i++)
    995     {
    996       uint32_t cp = EXTRACTOR_forensic_le16_ (&p[k + 2 * i]);
    997 
    998       if ( (0xD800 <= cp) && (0xDBFF >= cp) && (i + 1 < n16) )
    999       {
   1000         uint32_t lo = EXTRACTOR_forensic_le16_ (&p[k + 2 * (i + 1)]);
   1001 
   1002         if ( (0xDC00 <= lo) && (0xDFFF >= lo) )
   1003         {
   1004           cp = 0x10000 + ((cp - 0xD800) << 10) + (lo - 0xDC00);
   1005           i++;
   1006         }
   1007       }
   1008       if ( (0xD800 <= cp) && (0xDFFF >= cp) )
   1009         break;   /* unpaired surrogate; stop rather than guess */
   1010       if (cp < 0x80)
   1011       {
   1012         if (o + 2 > outsz)
   1013           break;
   1014         out[o++] = (char) cp;
   1015       }
   1016       else if (cp < 0x800)
   1017       {
   1018         if (o + 3 > outsz)
   1019           break;
   1020         out[o++] = (char) (0xC0 | (cp >> 6));
   1021         out[o++] = (char) (0x80 | (cp & 0x3F));
   1022       }
   1023       else if (cp < 0x10000)
   1024       {
   1025         if (o + 4 > outsz)
   1026           break;
   1027         out[o++] = (char) (0xE0 | (cp >> 12));
   1028         out[o++] = (char) (0x80 | ((cp >> 6) & 0x3F));
   1029         out[o++] = (char) (0x80 | (cp & 0x3F));
   1030       }
   1031       else
   1032       {
   1033         if (o + 5 > outsz)
   1034           break;
   1035         out[o++] = (char) (0xF0 | (cp >> 18));
   1036         out[o++] = (char) (0x80 | ((cp >> 12) & 0x3F));
   1037         out[o++] = (char) (0x80 | ((cp >> 6) & 0x3F));
   1038         out[o++] = (char) (0x80 | (cp & 0x3F));
   1039       }
   1040     }
   1041     out[o] = '\0';
   1042     return o;
   1043   }
   1044 }
   1045 
   1046 
   1047 /**
   1048  * Spell an Android API level as the marketing version people recognise.
   1049  *
   1050  * @param api the API level
   1051  * @return the version string, NULL if the level is not in the table
   1052  */
   1053 static const char *
   1054 android_release (uint32_t api)
   1055 {
   1056   static const char *table[] = {
   1057     NULL, "1.0", "1.1", "1.5", "1.6", "2.0", "2.0.1", "2.1", "2.2",
   1058     "2.3", "2.3.3", "3.0", "3.1", "3.2", "4.0", "4.0.3", "4.1", "4.2",
   1059     "4.3", "4.4", "4.4W", "5.0", "5.1", "6.0", "7.0", "7.1", "8.0",
   1060     "8.1", "9", "10", "11", "12", "12L", "13", "14", "15", "16"
   1061   };
   1062 
   1063   if ( (0 == api) ||
   1064        (api >= sizeof (table) / sizeof (table[0])) )
   1065     return NULL;
   1066   return table[api];
   1067 }
   1068 
   1069 
   1070 /**
   1071  * Report an API level, naming the Android release where we know it.
   1072  *
   1073  * @param ec extraction context
   1074  * @param type meta data type
   1075  * @param api the API level
   1076  * @return 1 if the caller should stop extracting, 0 to continue
   1077  */
   1078 static int
   1079 emit_api_level (struct EXTRACTOR_ExtractContext *ec,
   1080                 enum EXTRACTOR_MetaType type,
   1081                 uint32_t api)
   1082 {
   1083   const char *rel = android_release (api);
   1084 
   1085   if (NULL == rel)
   1086     return EXTRACTOR_forensic_emit_ (ec,
   1087                                      PLUGIN_NAME,
   1088                                      type,
   1089                                      "Android API %u",
   1090                                      (unsigned int) api);
   1091   return EXTRACTOR_forensic_emit_ (ec,
   1092                                    PLUGIN_NAME,
   1093                                    type,
   1094                                    "Android API %u (Android %s)",
   1095                                    (unsigned int) api,
   1096                                    rel);
   1097 }
   1098 
   1099 
   1100 /**
   1101  * Report the attributes of one AXML element, if it is an element we
   1102  * care about.
   1103  *
   1104  * @param ec extraction context
   1105  * @param sp the string pool
   1106  * @param element the element's name
   1107  * @param attrs pointer to the first attribute
   1108  * @param count number of attributes
   1109  * @param stride number of bytes per attribute
   1110  * @param[in,out] permissions number of permissions reported so far
   1111  * @param[in,out] have_sdk set once compileSdkVersion has been reported
   1112  * @return 1 if the caller should stop extracting, 0 to continue
   1113  */
   1114 static int
   1115 emit_element (struct EXTRACTOR_ExtractContext *ec,
   1116               const struct StringPool *sp,
   1117               const char *element,
   1118               const unsigned char *attrs,
   1119               unsigned int count,
   1120               size_t stride,
   1121               unsigned int *permissions,
   1122               int *have_sdk)
   1123 {
   1124   int is_manifest = (0 == strcmp (element, "manifest"));
   1125   int is_uses_sdk = (0 == strcmp (element, "uses-sdk"));
   1126   int is_permission = (0 == strcmp (element, "uses-permission"));
   1127   int is_application = (0 == strcmp (element, "application"));
   1128 
   1129   if (! (is_manifest || is_uses_sdk || is_permission || is_application))
   1130     return 0;
   1131   for (unsigned int i = 0; i < count; i++)
   1132   {
   1133     const unsigned char *a = &attrs[i * stride];
   1134     char name[128];
   1135     char value[EXTRACTOR_FORENSIC_MAX_STRING];
   1136     uint32_t data;
   1137     unsigned int dtype;
   1138 
   1139     if (0 == pool_string (sp,
   1140                           EXTRACTOR_forensic_le32_ (&a[4]),
   1141                           name,
   1142                           sizeof (name)))
   1143       continue;   /* attribute names are given by resource id only in
   1144                      files aapt did not produce; we do not guess */
   1145     dtype = a[15];
   1146     data = EXTRACTOR_forensic_le32_ (&a[16]);
   1147     value[0] = '\0';
   1148     if (TYPE_STRING == dtype)
   1149       (void) pool_string (sp,
   1150                           data,
   1151                           value,
   1152                           sizeof (value));
   1153     if (is_manifest)
   1154     {
   1155       if ( (0 == strcmp (name, "package")) &&
   1156            (TYPE_STRING == dtype) )
   1157       {
   1158         if (0 !=
   1159             EXTRACTOR_forensic_emit_text_ (ec,
   1160                                            PLUGIN_NAME,
   1161                                            EXTRACTOR_METATYPE_PACKAGE_NAME,
   1162                                            value,
   1163                                            strlen (value)))
   1164           return 1;
   1165       }
   1166       else if (0 == strcmp (name, "versionCode"))
   1167       {
   1168         if (TYPE_STRING == dtype)
   1169         {
   1170           if (0 !=
   1171               EXTRACTOR_forensic_emit_text_ (
   1172                 ec,
   1173                 PLUGIN_NAME,
   1174                 EXTRACTOR_METATYPE_PACKAGE_VERSION,
   1175                 value,
   1176                 strlen (value)))
   1177             return 1;
   1178         }
   1179         else if (0 !=
   1180                  EXTRACTOR_forensic_emit_ (
   1181                    ec,
   1182                    PLUGIN_NAME,
   1183                    EXTRACTOR_METATYPE_PACKAGE_VERSION,
   1184                    "%u",
   1185                    (unsigned int) data))
   1186           return 1;
   1187       }
   1188       else if ( (0 == strcmp (name, "versionName")) &&
   1189                 (TYPE_STRING == dtype) )
   1190       {
   1191         if (0 !=
   1192             EXTRACTOR_forensic_emit_text_ (
   1193               ec,
   1194               PLUGIN_NAME,
   1195               EXTRACTOR_METATYPE_SOFTWARE_VERSION,
   1196               value,
   1197               strlen (value)))
   1198           return 1;
   1199       }
   1200       else if ( (0 == strcmp (name, "compileSdkVersion")) &&
   1201                 (TYPE_STRING != dtype) )
   1202       {
   1203         *have_sdk = 1;
   1204         if (0 !=
   1205             emit_api_level (ec,
   1206                             EXTRACTOR_METATYPE_TOOLCHAIN,
   1207                             data))
   1208           return 1;
   1209       }
   1210       else if ( (0 == strcmp (name, "platformBuildVersionCode")) &&
   1211                 (TYPE_STRING != dtype) &&
   1212                 (! *have_sdk) )
   1213       {
   1214         /* what older builds of aapt wrote instead of
   1215            compileSdkVersion; reporting both would say the same thing
   1216            twice */
   1217         *have_sdk = 1;
   1218         if (0 !=
   1219             emit_api_level (ec,
   1220                             EXTRACTOR_METATYPE_TOOLCHAIN,
   1221                             data))
   1222           return 1;
   1223       }
   1224     }
   1225     else if (is_uses_sdk)
   1226     {
   1227       if ( (0 == strcmp (name, "minSdkVersion")) &&
   1228            (TYPE_STRING != dtype) )
   1229       {
   1230         if (0 !=
   1231             emit_api_level (ec,
   1232                             EXTRACTOR_METATYPE_MINIMUM_OS_VERSION,
   1233                             data))
   1234           return 1;
   1235       }
   1236       else if ( (0 == strcmp (name, "targetSdkVersion")) &&
   1237                 (TYPE_STRING != dtype) )
   1238       {
   1239         if (0 !=
   1240             emit_api_level (ec,
   1241                             EXTRACTOR_METATYPE_TARGET_OS,
   1242                             data))
   1243           return 1;
   1244       }
   1245     }
   1246     else if (is_permission)
   1247     {
   1248       if ( (0 != strcmp (name, "name")) ||
   1249            (TYPE_STRING != dtype) )
   1250         continue;
   1251       /* every declared permission is counted, but only the first few
   1252          dozen are reported: what matters on a first pass is the
   1253          characterisation, and the total is reported separately */
   1254       (*permissions)++;
   1255       if (*permissions > EXTRACTOR_FORENSIC_MAX_ITEMS)
   1256         continue;
   1257       if (0 !=
   1258           EXTRACTOR_forensic_emit_text_ (ec,
   1259                                          PLUGIN_NAME,
   1260                                          EXTRACTOR_METATYPE_PERMISSION,
   1261                                          value,
   1262                                          strlen (value)))
   1263         return 1;
   1264     }
   1265     else   /* is_application */
   1266     {
   1267       if (0 == strcmp (name, "label"))
   1268       {
   1269         /* usually a resource reference, and a bare `@0x7f...' would
   1270            tell nobody anything */
   1271         if (TYPE_STRING != dtype)
   1272           continue;
   1273         if (0 !=
   1274             EXTRACTOR_forensic_emit_text_ (ec,
   1275                                            PLUGIN_NAME,
   1276                                            EXTRACTOR_METATYPE_TITLE,
   1277                                            value,
   1278                                            strlen (value)))
   1279           return 1;
   1280       }
   1281       else if ( (0 == strcmp (name, "debuggable")) &&
   1282                 (TYPE_INT_BOOLEAN == dtype) &&
   1283                 (0 != data) )
   1284       {
   1285         /* a debuggable package that was shipped is worth a look */
   1286         if (0 !=
   1287             EXTRACTOR_forensic_emit_ (ec,
   1288                                       PLUGIN_NAME,
   1289                                       EXTRACTOR_METATYPE_ATTRIBUTES,
   1290                                       "debuggable"))
   1291           return 1;
   1292       }
   1293       else if ( ( (0 == strcmp (name, "allowBackup")) ||
   1294                   (0 == strcmp (name, "usesCleartextTraffic")) ||
   1295                   (0 == strcmp (name, "extractNativeLibs")) ) &&
   1296                 (TYPE_INT_BOOLEAN == dtype) )
   1297       {
   1298         if (0 !=
   1299             EXTRACTOR_forensic_emit_ (ec,
   1300                                       PLUGIN_NAME,
   1301                                       EXTRACTOR_METATYPE_ATTRIBUTES,
   1302                                       "%s: %s",
   1303                                       name,
   1304                                       (0 != data) ? "true" : "false"))
   1305           return 1;
   1306       }
   1307       else if (0 == strcmp (name, "networkSecurityConfig"))
   1308       {
   1309         if (0 !=
   1310             EXTRACTOR_forensic_emit_ (ec,
   1311                                       PLUGIN_NAME,
   1312                                       EXTRACTOR_METATYPE_ATTRIBUTES,
   1313                                       "networkSecurityConfig: %s",
   1314                                       ('\0' != value[0])
   1315                                       ? value
   1316                                       : "present"))
   1317           return 1;
   1318       }
   1319     }
   1320   }
   1321   return 0;
   1322 }
   1323 
   1324 
   1325 /**
   1326  * Walk a binary `AndroidManifest.xml'.
   1327  *
   1328  * The document is a flat list of chunks: a header, a string pool, an
   1329  * optional resource map, and then one chunk per XML event.  Only the
   1330  * start element chunks matter here, and only four element names, so the
   1331  * walk stays linear and never recurses.
   1332  *
   1333  * @param ec extraction context
   1334  * @param data the document
   1335  * @param len number of bytes in @a data
   1336  * @return 1 if the caller should stop extracting, 0 to continue
   1337  */
   1338 static int
   1339 parse_axml (struct EXTRACTOR_ExtractContext *ec,
   1340             const unsigned char *data,
   1341             size_t len)
   1342 {
   1343   struct StringPool sp;
   1344   size_t pos;
   1345   size_t total;
   1346   uint16_t hdr_size;
   1347   unsigned int chunks = 0;
   1348   unsigned int permissions = 0;
   1349   int have_sdk = 0;
   1350 
   1351   memset (&sp,
   1352           0,
   1353           sizeof (sp));
   1354   if (len < 8)
   1355     return 0;
   1356   if (RES_XML_TYPE != EXTRACTOR_forensic_le16_ (data))
   1357     return 0;
   1358   hdr_size = EXTRACTOR_forensic_le16_ (&data[2]);
   1359   total = (size_t) EXTRACTOR_forensic_le32_ (&data[4]);
   1360   if ( (hdr_size < 8) ||
   1361        (((size_t) hdr_size) > len) )
   1362     return 0;
   1363   if ( (total > len) ||
   1364        (total < 8) )
   1365     total = len;   /* truncated by our read cap, or by the file */
   1366   pos = hdr_size;
   1367   while ( (pos + 8 <= total) &&
   1368           (chunks++ < MAX_CHUNKS) )
   1369   {
   1370     uint16_t type = EXTRACTOR_forensic_le16_ (&data[pos]);
   1371     uint16_t chdr = EXTRACTOR_forensic_le16_ (&data[pos + 2]);
   1372     uint32_t csize = EXTRACTOR_forensic_le32_ (&data[pos + 4]);
   1373 
   1374     if ( (csize < 8) ||
   1375          (chdr < 8) ||
   1376          (((uint64_t) csize) > total - pos) ||
   1377          (chdr > csize) )
   1378       break;   /* malformed, or no forward progress */
   1379     if (RES_STRING_POOL_TYPE == type)
   1380     {
   1381       uint32_t count;
   1382       uint32_t flags;
   1383       uint32_t strings_start;
   1384       uint32_t styles_start;
   1385 
   1386       if (chdr < 28)
   1387       {
   1388         pos += csize;
   1389         continue;
   1390       }
   1391       count = EXTRACTOR_forensic_le32_ (&data[pos + 8]);
   1392       flags = EXTRACTOR_forensic_le32_ (&data[pos + 16]);
   1393       strings_start = EXTRACTOR_forensic_le32_ (&data[pos + 20]);
   1394       styles_start = EXTRACTOR_forensic_le32_ (&data[pos + 24]);
   1395       if ( (count > MAX_POOL_STRINGS) ||
   1396            (((uint64_t) count) * 4 > csize - 28) ||
   1397            (strings_start > csize) ||
   1398            (strings_start < 28) )
   1399       {
   1400         pos += csize;
   1401         continue;
   1402       }
   1403       sp.count = count;
   1404       sp.offsets = &data[pos + 28];
   1405       sp.data = &data[pos + strings_start];
   1406       sp.data_len = csize - strings_start;
   1407       if ( (0 != styles_start) &&
   1408            (styles_start > strings_start) &&
   1409            (styles_start <= csize) )
   1410         sp.data_len = styles_start - strings_start;
   1411       sp.utf8 = (0 != (flags & 0x100));
   1412     }
   1413     else if (RES_XML_START_ELEMENT_TYPE == type)
   1414     {
   1415       const unsigned char *ext;
   1416       char element[128];
   1417       uint16_t attr_start;
   1418       uint16_t attr_size;
   1419       uint16_t attr_count;
   1420       uint64_t need;
   1421 
   1422       if ( (chdr < 16) ||
   1423            (csize - chdr < 20) )
   1424       {
   1425         pos += csize;
   1426         continue;
   1427       }
   1428       ext = &data[pos + chdr];
   1429       attr_start = EXTRACTOR_forensic_le16_ (&ext[8]);
   1430       attr_size = EXTRACTOR_forensic_le16_ (&ext[10]);
   1431       attr_count = EXTRACTOR_forensic_le16_ (&ext[12]);
   1432       /* every attribute is a ResXMLTree_attribute: four 32 bit words
   1433          plus a Res_value, and implementations are allowed to make the
   1434          record longer, never shorter */
   1435       if (attr_size < 20)
   1436       {
   1437         pos += csize;
   1438         continue;
   1439       }
   1440       need = ((uint64_t) attr_start)
   1441              + ((uint64_t) attr_count) * attr_size;
   1442       if (need > (uint64_t) (csize - chdr))
   1443       {
   1444         pos += csize;
   1445         continue;
   1446       }
   1447       if (0 == pool_string (&sp,
   1448                             EXTRACTOR_forensic_le32_ (&ext[4]),
   1449                             element,
   1450                             sizeof (element)))
   1451       {
   1452         pos += csize;
   1453         continue;
   1454       }
   1455       if (0 !=
   1456           emit_element (ec,
   1457                         &sp,
   1458                         element,
   1459                         &data[pos + chdr + attr_start],
   1460                         attr_count,
   1461                         attr_size,
   1462                         &permissions,
   1463                         &have_sdk))
   1464         return 1;
   1465     }
   1466     pos += csize;
   1467   }
   1468   if (permissions > EXTRACTOR_FORENSIC_MAX_ITEMS)
   1469     return EXTRACTOR_forensic_emit_ (ec,
   1470                                      PLUGIN_NAME,
   1471                                      EXTRACTOR_METATYPE_COMMENT,
   1472                                      "%u permissions declared",
   1473                                      permissions);
   1474   return 0;
   1475 }
   1476 
   1477 
   1478 /* ------------------------------------------------------------------ */
   1479 /* ZIP container                                                       */
   1480 /* ------------------------------------------------------------------ */
   1481 
   1482 
   1483 /**
   1484  * Walk the ZIP central directory once and note the things that can be
   1485  * read off member names alone.
   1486  *
   1487  * @param uf the archive
   1488  * @param[out] af where to store what we found
   1489  */
   1490 static void
   1491 scan_members (struct EXTRACTOR_UnzipFile *uf,
   1492               struct ArchiveFacts *af)
   1493 {
   1494   char name[512];
   1495   unsigned int seen = 0;
   1496 
   1497   memset (af,
   1498           0,
   1499           sizeof (*af));
   1500   if (EXTRACTOR_UNZIP_OK !=
   1501       EXTRACTOR_common_unzip_go_to_first_file (uf))
   1502     return;
   1503   do
   1504   {
   1505     size_t nlen;
   1506 
   1507     if (seen++ >= MAX_MEMBERS)
   1508       break;
   1509     if (EXTRACTOR_UNZIP_OK !=
   1510         EXTRACTOR_common_unzip_get_current_file_info (uf,
   1511                                                       NULL,
   1512                                                       name,
   1513                                                       sizeof (name),
   1514                                                       NULL, 0,
   1515                                                       NULL, 0))
   1516       continue;
   1517     af->num_members++;
   1518     nlen = strlen (name);
   1519     if ( (0 == strncmp (name, "classes", strlen ("classes"))) &&
   1520          (4 < nlen) &&
   1521          (0 == strcmp (&name[nlen - 4], ".dex")) )
   1522     {
   1523       af->num_dex++;
   1524       continue;
   1525     }
   1526     if (0 == strncmp (name, "lib/", strlen ("lib/")))
   1527     {
   1528       const char *abi = &name[strlen ("lib/")];
   1529       const char *slash = strchr (abi, '/');
   1530       size_t alen;
   1531 
   1532       if (NULL == slash)
   1533         continue;
   1534       alen = (size_t) (slash - abi);
   1535       if ( (0 == alen) ||
   1536            (alen >= sizeof (af->abis[0])) )
   1537         continue;
   1538       for (unsigned int i = 0; i < af->num_abis; i++)
   1539         if ( (0 == strncmp (af->abis[i], abi, alen)) &&
   1540              ('\0' == af->abis[i][alen]) )
   1541         {
   1542           alen = 0;
   1543           break;
   1544         }
   1545       if (0 == alen)
   1546         continue;
   1547       if (af->num_abis >= sizeof (af->abis) / sizeof (af->abis[0]))
   1548         continue;
   1549       memcpy (af->abis[af->num_abis],
   1550               abi,
   1551               alen);
   1552       af->abis[af->num_abis][alen] = '\0';
   1553       af->num_abis++;
   1554       continue;
   1555     }
   1556     if ( ('\0' == af->sig_member[0]) &&
   1557          (0 == strncmp (name, "META-INF/", strlen ("META-INF/"))) &&
   1558          (4 < nlen) &&
   1559          ( (0 == strcasecmp (&name[nlen - 4], ".RSA")) ||
   1560            (0 == strcasecmp (&name[nlen - 4], ".DSA")) ) )
   1561     {
   1562       const char *base = &name[strlen ("META-INF/")];
   1563 
   1564       if (NULL == strchr (base, '/'))
   1565       {
   1566         memcpy (af->sig_member,
   1567                 name,
   1568                 (nlen < sizeof (af->sig_member))
   1569                 ? nlen + 1
   1570                 : sizeof (af->sig_member));
   1571         af->sig_member[sizeof (af->sig_member) - 1] = '\0';
   1572         snprintf (af->sig_alias,
   1573                   sizeof (af->sig_alias),
   1574                   "%.*s",
   1575                   (int) (strlen (base) - 4),
   1576                   base);
   1577       }
   1578     }
   1579   }
   1580   while (EXTRACTOR_UNZIP_OK ==
   1581          EXTRACTOR_common_unzip_go_to_next_file (uf));
   1582 }
   1583 
   1584 
   1585 /**
   1586  * Report which APK signature schemes the file carries.
   1587  *
   1588  * The v2 and v3 signatures live in an "APK Signing Block", which sits
   1589  * between the last local file entry and the central directory and is
   1590  * found from the end: the block ends with its own size and the magic
   1591  * string `APK Sig Block 42' immediately before the central directory.
   1592  *
   1593  * @param ec extraction context
   1594  * @return 1 if the caller should stop extracting, 0 to continue
   1595  */
   1596 static int
   1597 emit_signing_block (struct EXTRACTOR_ExtractContext *ec)
   1598 {
   1599   unsigned char eocd[22];
   1600   unsigned char foot[24];
   1601   unsigned char *block;
   1602   uint64_t size;
   1603   uint64_t cd_off;
   1604   uint64_t block_size;
   1605   uint64_t start;
   1606   size_t read_len;
   1607   size_t pos;
   1608   int ret = 0;
   1609 
   1610   size = ec->get_size (ec->cls);
   1611   if ( (UINT64_MAX == size) ||
   1612        (size < 22 + 24) )
   1613     return 0;
   1614   /* the usual case is an archive with no comment, so the end of central
   1615      directory record is the last 22 bytes */
   1616   if (! EXTRACTOR_forensic_read_ (ec,
   1617                                   (int64_t) (size - 22),
   1618                                   eocd,
   1619                                   sizeof (eocd)))
   1620     return 0;
   1621   if (0 != memcmp (eocd,
   1622                    "PK\x05\x06",
   1623                    4))
   1624   {
   1625     unsigned char *tail;
   1626     size_t tail_len = (size > 65557) ? 65557 : (size_t) size;
   1627     const unsigned char *found = NULL;
   1628 
   1629     if (NULL == (tail = malloc (tail_len)))
   1630       return 0;
   1631     if (EXTRACTOR_forensic_read_ (ec,
   1632                                   (int64_t) (size - tail_len),
   1633                                   tail,
   1634                                   tail_len))
   1635       for (size_t i = tail_len - 22 + 1; i-- > 0;)
   1636         if (0 == memcmp (&tail[i],
   1637                          "PK\x05\x06",
   1638                          4))
   1639         {
   1640           found = &tail[i];
   1641           break;
   1642         }
   1643     if (NULL == found)
   1644     {
   1645       free (tail);
   1646       return 0;
   1647     }
   1648     memcpy (eocd,
   1649             found,
   1650             sizeof (eocd));
   1651     free (tail);
   1652   }
   1653   cd_off = EXTRACTOR_forensic_le32_ (&eocd[16]);
   1654   if ( (cd_off < 24) ||
   1655        (cd_off > size) )
   1656     return 0;
   1657   if (! EXTRACTOR_forensic_read_ (ec,
   1658                                   (int64_t) (cd_off - 24),
   1659                                   foot,
   1660                                   sizeof (foot)))
   1661     return 0;
   1662   if (0 != memcmp (&foot[8],
   1663                    "APK Sig Block 42",
   1664                    16))
   1665     return 0;
   1666   block_size = EXTRACTOR_forensic_le64_ (&foot[0]);
   1667   /* written as a subtraction so that a huge size field cannot overflow;
   1668      cd_off is at least 24 here */
   1669   if ( (block_size < 24) ||
   1670        (block_size > cd_off - 8) )
   1671     return 0;
   1672   start = cd_off - block_size - 8;
   1673   /* the pairs run from just after the leading size field up to the
   1674      trailing size field */
   1675   read_len = (size_t) (block_size - 24);
   1676   if (read_len > MAX_SIG_BLOCK)
   1677     read_len = MAX_SIG_BLOCK;
   1678   if (0 == read_len)
   1679     return 0;
   1680   if (NULL == (block = malloc (read_len)))
   1681     return 0;
   1682   if (! EXTRACTOR_forensic_read_ (ec,
   1683                                   (int64_t) (start + 8),
   1684                                   block,
   1685                                   read_len))
   1686   {
   1687     free (block);
   1688     return 0;
   1689   }
   1690   pos = 0;
   1691   for (unsigned int i = 0; (i < 64) && (pos + 12 <= read_len); i++)
   1692   {
   1693     uint64_t plen = EXTRACTOR_forensic_le64_ (&block[pos]);
   1694     uint32_t id = EXTRACTOR_forensic_le32_ (&block[pos + 8]);
   1695     const char *scheme = NULL;
   1696 
   1697     if (plen < 4)
   1698       break;   /* no forward progress */
   1699     switch (id)
   1700     {
   1701     case APK_SIG_SCHEME_V2: scheme = "v2"; break;
   1702     case APK_SIG_SCHEME_V3: scheme = "v3"; break;
   1703     case APK_SIG_SCHEME_V31: scheme = "v3.1"; break;
   1704     default: break;
   1705     }
   1706     if ( (NULL != scheme) &&
   1707          (0 !=
   1708           EXTRACTOR_forensic_emit_ (ec,
   1709                                     PLUGIN_NAME,
   1710                                     EXTRACTOR_METATYPE_SIGNER,
   1711                                     "APK Signature Scheme %s",
   1712                                     scheme)) )
   1713     {
   1714       ret = 1;
   1715       break;
   1716     }
   1717     if (plen > read_len - pos - 8)
   1718       break;
   1719     pos += (size_t) plen + 8;
   1720   }
   1721   free (block);
   1722   return ret;
   1723 }
   1724 
   1725 
   1726 /**
   1727  * Report who signed the archive.
   1728  *
   1729  * @param ec extraction context
   1730  * @param uf the archive
   1731  * @param af what the central directory walk found
   1732  * @return 1 if the caller should stop extracting, 0 to continue
   1733  */
   1734 static int
   1735 emit_signature (struct EXTRACTOR_ExtractContext *ec,
   1736                 struct EXTRACTOR_UnzipFile *uf,
   1737                 const struct ArchiveFacts *af)
   1738 {
   1739   unsigned char *der;
   1740   size_t der_len;
   1741   char dn[EXTRACTOR_FORENSIC_MAX_STRING];
   1742   int ret = 0;
   1743 
   1744   if ('\0' == af->sig_member[0])
   1745     return 0;
   1746   if (0 !=
   1747       EXTRACTOR_forensic_emit_ (ec,
   1748                                 PLUGIN_NAME,
   1749                                 EXTRACTOR_METATYPE_SIGNER,
   1750                                 "JAR signing (v1), alias %s",
   1751                                 af->sig_alias))
   1752     return 1;
   1753   der = read_member (uf,
   1754                      af->sig_member,
   1755                      MAX_PKCS7,
   1756                      &der_len);
   1757   if (NULL == der)
   1758     return 0;
   1759   if (pkcs7_signer_dn (der,
   1760                        der_len,
   1761                        dn,
   1762                        sizeof (dn)))
   1763     ret = EXTRACTOR_forensic_emit_text_ (ec,
   1764                                          PLUGIN_NAME,
   1765                                          EXTRACTOR_METATYPE_SIGNER,
   1766                                          dn,
   1767                                          strlen (dn));
   1768   free (der);
   1769   return ret;
   1770 }
   1771 
   1772 
   1773 /**
   1774  * Report the facts that follow from the member names alone.
   1775  *
   1776  * @param ec extraction context
   1777  * @param af what the central directory walk found
   1778  * @return 1 if the caller should stop extracting, 0 to continue
   1779  */
   1780 static int
   1781 emit_archive_facts (struct EXTRACTOR_ExtractContext *ec,
   1782                     const struct ArchiveFacts *af)
   1783 {
   1784   for (unsigned int i = 0; i < af->num_abis; i++)
   1785     if (0 !=
   1786         EXTRACTOR_forensic_emit_text_ (
   1787           ec,
   1788           PLUGIN_NAME,
   1789           EXTRACTOR_METATYPE_TARGET_ARCHITECTURE,
   1790           af->abis[i],
   1791           strlen (af->abis[i])))
   1792       return 1;
   1793   if ( (0 != af->num_dex) &&
   1794        (0 !=
   1795         EXTRACTOR_forensic_emit_ (ec,
   1796                                   PLUGIN_NAME,
   1797                                   EXTRACTOR_METATYPE_COMMENT,
   1798                                   "%u dex file%s",
   1799                                   af->num_dex,
   1800                                   (1 == af->num_dex) ? "" : "s")) )
   1801     return 1;
   1802   if ( (0 != af->num_members) &&
   1803        (0 !=
   1804         EXTRACTOR_forensic_emit_ (ec,
   1805                                   PLUGIN_NAME,
   1806                                   EXTRACTOR_METATYPE_ENTRY_COUNT,
   1807                                   "%u",
   1808                                   af->num_members)) )
   1809     return 1;
   1810   return 0;
   1811 }
   1812 
   1813 
   1814 /**
   1815  * Main entry method for the apk extraction plugin.
   1816  *
   1817  * @param ec extraction context provided to the plugin
   1818  */
   1819 void
   1820 EXTRACTOR_apk_extract_method (struct EXTRACTOR_ExtractContext *ec);
   1821 
   1822 void
   1823 EXTRACTOR_apk_extract_method (struct EXTRACTOR_ExtractContext *ec)
   1824 {
   1825   unsigned char magic[4];
   1826   struct EXTRACTOR_UnzipFile *uf;
   1827   struct ArchiveFacts af;
   1828   unsigned char *member;
   1829   size_t member_len;
   1830   int is_apk;
   1831 
   1832   if (! EXTRACTOR_forensic_read_ (ec,
   1833                                   0,
   1834                                   magic,
   1835                                   sizeof (magic)))
   1836     return;
   1837   if (0 != memcmp (magic,
   1838                    "PK\x03\x04",
   1839                    4))
   1840     return;
   1841   if (NULL == (uf = EXTRACTOR_common_unzip_open (ec)))
   1842     return;
   1843   /* an APK contains a JAR manifest too, so look for the Android
   1844      manifest first */
   1845   if (EXTRACTOR_UNZIP_OK ==
   1846       EXTRACTOR_common_unzip_go_find_local_file (uf,
   1847                                                  "AndroidManifest.xml",
   1848                                                  2))
   1849   {
   1850     is_apk = 1;
   1851   }
   1852   else if (EXTRACTOR_UNZIP_OK ==
   1853            EXTRACTOR_common_unzip_go_find_local_file (uf,
   1854                                                       "META-INF/MANIFEST.MF",
   1855                                                       2))
   1856   {
   1857     is_apk = 0;
   1858   }
   1859   else
   1860   {
   1861     (void) EXTRACTOR_common_unzip_close (uf);
   1862     return;   /* somebody else's ZIP */
   1863   }
   1864   if (0 !=
   1865       ec->proc (ec->cls,
   1866                 PLUGIN_NAME,
   1867                 EXTRACTOR_METATYPE_MIMETYPE,
   1868                 EXTRACTOR_METAFORMAT_UTF8,
   1869                 "text/plain",
   1870                 is_apk
   1871                 ? "application/vnd.android.package-archive"
   1872                 : "application/java-archive",
   1873                 is_apk
   1874                 ? strlen ("application/vnd.android.package-archive") + 1
   1875                 : strlen ("application/java-archive") + 1))
   1876     goto CLEANUP;
   1877   if (is_apk)
   1878   {
   1879     member = read_member (uf,
   1880                           "AndroidManifest.xml",
   1881                           MAX_AXML,
   1882                           &member_len);
   1883     if (NULL != member)
   1884     {
   1885       int stop = parse_axml (ec,
   1886                              member,
   1887                              member_len);
   1888 
   1889       free (member);
   1890       if (stop)
   1891         goto CLEANUP;
   1892     }
   1893   }
   1894   else
   1895   {
   1896     member = read_member (uf,
   1897                           "META-INF/MANIFEST.MF",
   1898                           MAX_MANIFEST,
   1899                           &member_len);
   1900     if (NULL != member)
   1901     {
   1902       int stop = parse_jar_manifest (ec,
   1903                                      (const char *) member,
   1904                                      member_len);
   1905 
   1906       free (member);
   1907       if (stop)
   1908         goto CLEANUP;
   1909     }
   1910   }
   1911   scan_members (uf,
   1912                 &af);
   1913   if (0 !=
   1914       emit_archive_facts (ec,
   1915                           &af))
   1916     goto CLEANUP;
   1917   if (0 !=
   1918       emit_signature (ec,
   1919                       uf,
   1920                       &af))
   1921     goto CLEANUP;
   1922   if (is_apk)
   1923     (void) emit_signing_block (ec);
   1924 CLEANUP:
   1925   (void) EXTRACTOR_common_unzip_close (uf);
   1926 }
   1927 
   1928 
   1929 /* end of apk_extractor.c */