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