Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / components / crx_file / crx_file.cc
1 // Copyright 2014 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 "components/crx_file/crx_file.h"
6
7 namespace crx_file {
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 crx_file