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.
5 #include "extensions/common/crx_file.h"
11 // The current version of the crx format.
12 static const uint32 kCurrentVersion
= 2;
14 // The current version of the crx diff format.
15 static const uint32 kCurrentDiffVersion
= 0;
17 // The maximum size the crx parser will tolerate for a public key.
18 static const uint32 kMaxPublicKeySize
= 1 << 16;
20 // The maximum size the crx parser will tolerate for a signature.
21 static const uint32 kMaxSignatureSize
= 1 << 16;
25 // The magic string embedded in the header.
26 const char kCrxFileHeaderMagic
[] = "Cr24";
27 const char kCrxDiffFileHeaderMagic
[] = "CrOD";
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
>();
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
>();
49 CrxFile::CrxFile(const Header
& header
) : header_(header
) {
52 bool CrxFile::HeaderIsDelta(const CrxFile::Header
& header
) {
53 return !strncmp(kCrxDiffFileHeaderMagic
, header
.magic
, sizeof(header
.magic
));
56 bool CrxFile::HeaderIsValid(const CrxFile::Header
& header
,
57 CrxFile::Error
* error
) {
60 if (!strncmp(kCrxDiffFileHeaderMagic
, header
.magic
, sizeof(header
.magic
)))
62 if (strncmp(kCrxFileHeaderMagic
, header
.magic
, sizeof(header
.magic
)) &&
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
;
81 } // namespace extensions