Home | History | Annotate | Download | only in common
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "extensions/common/crx_file.h"
      6 
      7 namespace extensions {
      8 
      9 namespace {
     10 
     11 // The current version of the crx format.
     12 static const uint32 kCurrentVersion = 2;
     13 
     14 // The current version of the crx diff format.
     15 static const uint32 kCurrentDiffVersion = 0;
     16 
     17 // The maximum size the crx parser will tolerate for a public key.
     18 static const uint32 kMaxPublicKeySize = 1 << 16;
     19 
     20 // The maximum size the crx parser will tolerate for a signature.
     21 static const uint32 kMaxSignatureSize = 1 << 16;
     22 
     23 }  // namespace
     24 
     25 // The magic string embedded in the header.
     26 const char kCrxFileHeaderMagic[] = "Cr24";
     27 const char kCrxDiffFileHeaderMagic[] = "CrOD";
     28 
     29 scoped_ptr<CrxFile> CrxFile::Parse(const CrxFile::Header& header,
     30                                    CrxFile::Error* error) {
     31   if (HeaderIsValid(header, error))
     32     return scoped_ptr<CrxFile>(new CrxFile(header));
     33   return scoped_ptr<CrxFile>();
     34 }
     35 
     36 scoped_ptr<CrxFile> CrxFile::Create(const uint32 key_size,
     37                                     const uint32 signature_size,
     38                                     CrxFile::Error* error) {
     39   CrxFile::Header header;
     40   memcpy(&header.magic, kCrxFileHeaderMagic, kCrxFileHeaderMagicSize);
     41   header.version = kCurrentVersion;
     42   header.key_size = key_size;
     43   header.signature_size = signature_size;
     44   if (HeaderIsValid(header, error))
     45     return scoped_ptr<CrxFile>(new CrxFile(header));
     46   return scoped_ptr<CrxFile>();
     47 }
     48 
     49 CrxFile::CrxFile(const Header& header) : header_(header) {
     50 }
     51 
     52 bool CrxFile::HeaderIsDelta(const CrxFile::Header& header) {
     53   return !strncmp(kCrxDiffFileHeaderMagic, header.magic, sizeof(header.magic));
     54 }
     55 
     56 bool CrxFile::HeaderIsValid(const CrxFile::Header& header,
     57                             CrxFile::Error* error) {
     58   bool valid = false;
     59   bool diffCrx = false;
     60   if (!strncmp(kCrxDiffFileHeaderMagic, header.magic, sizeof(header.magic)))
     61     diffCrx = true;
     62   if (strncmp(kCrxFileHeaderMagic, header.magic, sizeof(header.magic)) &&
     63       !diffCrx)
     64     *error = kWrongMagic;
     65   else if (header.version != kCurrentVersion
     66       && !(diffCrx && header.version == kCurrentDiffVersion))
     67     *error = kInvalidVersion;
     68   else if (header.key_size > kMaxPublicKeySize)
     69     *error = kInvalidKeyTooLarge;
     70   else if (header.key_size == 0)
     71     *error = kInvalidKeyTooSmall;
     72   else if (header.signature_size > kMaxSignatureSize)
     73     *error = kInvalidSignatureTooLarge;
     74   else if (header.signature_size == 0)
     75     *error = kInvalidSignatureTooSmall;
     76   else
     77     valid = true;
     78   return valid;
     79 }
     80 
     81 }  // namespace extensions
     82