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#ifndef EXTENSIONS_COMMON_CRX_FILE_H_
6#define EXTENSIONS_COMMON_CRX_FILE_H_
7
8#include <sys/types.h>
9#include "base/basictypes.h"
10#include "base/memory/scoped_ptr.h"
11
12namespace extensions {
13
14// CRX files have a header that includes a magic key, version number, and
15// some signature sizing information. Use CrxFile object to validate whether
16// the header is valid or not.
17class CrxFile {
18 public:
19  // The size of the magic character sequence at the beginning of each crx
20  // file, in bytes. This should be a multiple of 4.
21  static const size_t kCrxFileHeaderMagicSize = 4;
22
23  // This header is the first data at the beginning of an extension. Its
24  // contents are purposely 32-bit aligned so that it can just be slurped into
25  // a struct without manual parsing.
26  struct Header {
27    char magic[kCrxFileHeaderMagicSize];
28    uint32 version;
29    uint32 key_size;  // The size of the public key, in bytes.
30    uint32 signature_size;  // The size of the signature, in bytes.
31    // An ASN.1-encoded PublicKeyInfo structure follows.
32    // The signature follows.
33  };
34
35  enum Error {
36    kWrongMagic,
37    kInvalidVersion,
38    kInvalidKeyTooLarge,
39    kInvalidKeyTooSmall,
40    kInvalidSignatureTooLarge,
41    kInvalidSignatureTooSmall,
42  };
43
44  // Construct a new CRX file header object with bytes of a header
45  // read from a CRX file. If a null scoped_ptr is returned, |error|
46  // contains an error code with additional information.
47  static scoped_ptr<CrxFile> Parse(const Header& header, Error* error);
48
49  // Construct a new header for the given key and signature sizes.
50  // Returns a null scoped_ptr if erroneous values of |key_size| and/or
51  // |signature_size| are provided. |error| contains an error code with
52  // additional information.
53  // Use this constructor and then .header() to obtain the Header
54  // for writing out to a CRX file.
55  static scoped_ptr<CrxFile> Create(const uint32 key_size,
56                                    const uint32 signature_size,
57                                    Error* error);
58
59  // Returns the header structure for writing out to a CRX file.
60  const Header& header() const { return header_; }
61
62  // Checks a valid |header| to determine whether or not the CRX represents a
63  // differential CRX.
64  static bool HeaderIsDelta(const Header& header);
65
66 private:
67  Header header_;
68
69  // Constructor is private. Clients should use static factory methods above.
70  explicit CrxFile(const Header& header);
71
72  // Checks the |header| for validity and returns true if the values are valid.
73  // If false is returned, more detailed error code is returned in |error|.
74  static bool HeaderIsValid(const Header& header, Error* error);
75};
76
77}  // namespace extensions
78
79#endif  // EXTENSIONS_COMMON_CRX_FILE_H_
80