Refactor SignatureValidator and reduce interface headers
[platform/core/security/cert-svc.git] / vcore / vcore / SignatureFinder.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16 /*
17  * @file        SignatureFinder.cpp
18  * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
19  * @version     1.0
20  * @brief       Search for author-signature.xml and signatureN.xml files.
21  */
22 #include <vcore/SignatureFinder.h>
23 #include <dpl/log/log.h>
24
25 #include <dirent.h>
26 #include <errno.h>
27 #include <istream>
28 #include <sstream>
29
30 #include <pcrecpp.h>
31
32 namespace {
33
34 }
35
36 namespace ValidationCore {
37 static const char *SIGNATURE_AUTHOR = "author-signature.xml";
38 static const char *REGEXP_DISTRIBUTOR_SIGNATURE =
39     "^(signature)([1-9][0-9]*)(\\.xml)";
40
41 class SignatureFinder::Impl {
42 public:
43     Impl(const std::string& dir)
44       : m_dir(dir)
45       , m_signatureRegexp(REGEXP_DISTRIBUTOR_SIGNATURE)
46     {}
47
48     virtual ~Impl(){}
49
50     Result find(SignatureFileInfoSet &set);
51
52 private:
53     std::string getFullPath(const std::string &file);
54
55     std::string m_dir;
56     pcrecpp::RE m_signatureRegexp;
57 };
58
59 std::string SignatureFinder::Impl::getFullPath(const std::string &file)
60 {
61     std::string fullPath = m_dir;
62
63     if (fullPath.back() != '/')
64         fullPath += "/";
65
66     fullPath += file;
67
68     return fullPath;
69 }
70
71 SignatureFinder::Result SignatureFinder::Impl::find(SignatureFileInfoSet &set)
72 {
73     DIR *dp;
74     struct dirent *dirp;
75
76     if ((dp = opendir(m_dir.c_str())) == NULL) {
77         LogError("Error opening directory: " << m_dir);
78         return ERROR_OPENING_DIR;
79     }
80
81     for (errno = 0; (dirp = readdir(dp)) != NULL; errno = 0) {
82         /* number for author signature is -1 */
83         if (!strcmp(dirp->d_name, SIGNATURE_AUTHOR)) {
84             std::string fullPath = getFullPath(std::string(dirp->d_name));
85             LogDebug("Found author signature file full path : " << fullPath);
86             set.insert(SignatureFileInfo(fullPath, -1));
87             continue;
88         }
89
90         std::string sig;
91         std::string num;
92         std::string xml; /* just for cutting out .xml */
93         if (m_signatureRegexp.FullMatch(dirp->d_name, &sig, &num, &xml)) {
94             std::istringstream stream(num);
95             int number;
96             stream >> number;
97
98             if (stream.fail()) {
99                 closedir(dp);
100                 return ERROR_ISTREAM;
101             }
102
103             std::string fullPath = getFullPath(std::string(dirp->d_name));
104             LogDebug("Found signature file full path : " << fullPath);
105             set.insert(SignatureFileInfo(fullPath, number));
106         }
107     }
108
109     if (errno != 0) {
110         LogError("Error in readdir");
111         closedir(dp);
112         return ERROR_READING_DIR;
113     }
114
115     closedir(dp);
116     return NO_ERROR;
117 }
118
119 SignatureFinder::SignatureFinder(const std::string& dir)
120   : m_impl(new Impl(dir))
121 {}
122
123 SignatureFinder::~SignatureFinder()
124 {
125     delete m_impl;
126 }
127
128 SignatureFinder::Result SignatureFinder::find(SignatureFileInfoSet &set) {
129     return m_impl->find(set);
130 }
131
132 } // namespace ValidationCore