Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / xwalk / application / common / package / xpk_package.cc
1 // Copyright (c) 2013 Intel Corporation. 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 "xwalk/application/common/package/xpk_package.h"
6
7 #include "base/file_util.h"
8 #include "base/files/scoped_file.h"
9 #include "crypto/signature_verifier.h"
10 #include "xwalk/application/common/id_util.h"
11
12 namespace xwalk {
13 namespace application {
14
15 const uint8 kSignatureAlgorithm[15] = {
16   0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
17   0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00
18 };
19
20 const char XPKPackage::kXPKPackageHeaderMagic[] = "CrWk";
21
22 XPKPackage::~XPKPackage() {
23 }
24
25 XPKPackage::XPKPackage(const base::FilePath& path)
26   : Package(path) {
27   if (!base::PathExists(path))
28     return;
29   type_ = XPK;
30   scoped_ptr<base::ScopedFILE> file(
31       new base::ScopedFILE(base::OpenFile(path, "rb")));
32   file_ = file.Pass();
33   size_t len = fread(&header_, 1, sizeof(header_), file_->get());
34   is_valid_ = false;
35   if (len < sizeof(header_))
36     return;
37   if (!strncmp(XPKPackage::kXPKPackageHeaderMagic,
38                header_.magic,
39                sizeof(header_.magic)) &&
40       header_.key_size > 0 &&
41       header_.key_size <= XPKPackage::kMaxPublicKeySize &&
42       header_.signature_size > 0 &&
43       header_.signature_size <= XPKPackage::kMaxSignatureKeySize) {
44       is_valid_ = true;
45       zip_addr_ = sizeof(header_) + header_.key_size + header_.signature_size;
46         fseek(file_->get(), sizeof(header_), SEEK_SET);
47         key_.resize(header_.key_size);
48         size_t len = fread(
49             &key_.front(), sizeof(uint8), header_.key_size, file_->get());
50         if (len < header_.key_size)
51           is_valid_ = false;
52
53         signature_.resize(header_.signature_size);
54         len = fread(&signature_.front(),
55                     sizeof(uint8),
56                     header_.signature_size,
57                     file_->get());
58         if (len < header_.signature_size)
59           is_valid_ = false;
60
61         if (!VerifySignature())
62           is_valid_ = false;
63
64         std::string public_key =
65             std::string(reinterpret_cast<char*>(&key_.front()), key_.size());
66         id_ = GenerateId(public_key);
67   }
68 }
69
70 bool XPKPackage::VerifySignature() {
71 // Set the file read position to the beginning of compressed resource file,
72 // which is behind the magic header, public key and signature key.
73   fseek(file_->get(), zip_addr_, SEEK_SET);
74   crypto::SignatureVerifier verifier;
75   if (!verifier.VerifyInit(kSignatureAlgorithm,
76                            sizeof(kSignatureAlgorithm),
77                            &signature_.front(),
78                            signature_.size(),
79                            &key_.front(),
80                            key_.size()))
81     return false;
82   unsigned char buf[1 << 12];
83   size_t len = 0;
84   while ((len = fread(buf, 1, sizeof(buf), file_->get())) > 0)
85     verifier.VerifyUpdate(buf, len);
86   if (!verifier.VerifyFinal())
87     return false;
88
89   return true;
90 }
91
92 bool XPKPackage::ExtractToTemporaryDir(base::FilePath* target_path) {
93   if (is_extracted_) {
94     *target_path = temp_dir_.path();
95     return true;
96   }
97
98   if (!IsValid()) {
99     LOG(ERROR) << "The XPK file is not valid.";
100     return false;
101   }
102
103   return Package::ExtractToTemporaryDir(target_path);
104 }
105
106 }  // namespace application
107 }  // namespace xwalk