OSDN Git Service

Update license.
[qt-creator-jp/qt-creator-jp.git] / src / plugins / qt4projectmanager / qt-s60 / s60certificateinfo.cpp
1 /**************************************************************************
2 **
3 ** This file is part of Qt Creator
4 **
5 ** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
6 **
7 ** Contact: Nokia Corporation (info@qt.nokia.com)
8 **
9 **
10 ** GNU Lesser General Public License Usage
11 **
12 ** This file may be used under the terms of the GNU Lesser General Public
13 ** License version 2.1 as published by the Free Software Foundation and
14 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
15 ** Please review the following information to ensure the GNU Lesser General
16 ** Public License version 2.1 requirements will be met:
17 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 **
19 ** In addition, as a special exception, Nokia gives you certain additional
20 ** rights. These rights are described in the Nokia Qt LGPL Exception
21 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 **
23 ** Other Usage
24 **
25 ** Alternatively, this file may be used in accordance with the terms and
26 ** conditions contained in a signed written agreement between you and Nokia.
27 **
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
30 **
31 **************************************************************************/
32
33 #include "s60certificateinfo.h"
34 #include "s60symbiancertificate.h"
35
36 #include <QtCore/QDateTime>
37 #include <QtCore/QFileInfo>
38 #include <QtCore/QCoreApplication>
39 #include <QtCore/QTextStream>
40 #include <QtCore/QHash>
41 #include <QtCore/QMutableHashIterator>
42
43 using namespace Qt4ProjectManager;
44 using namespace Qt4ProjectManager::Internal;
45
46 namespace {
47     const char * const SIMPLE_DATE_FORMAT = "dd.MM.yyyy";
48 }
49
50 struct Capability {
51     const char *name;
52     const int value;
53 };
54
55 static const Capability capability[] =
56 {
57     { "LocalServices", S60CertificateInfo::LocalServices },
58     { "Location", S60CertificateInfo::Location },
59     { "NetworkServices", S60CertificateInfo::NetworkServices },
60     { "ReadUserData", S60CertificateInfo::ReadUserData },
61     { "UserEnvironment", S60CertificateInfo::UserEnvironment },
62     { "WriteUserData", S60CertificateInfo::WriteUserData },
63     { "PowerMgmt", S60CertificateInfo::PowerMgmt },
64     { "ProtServ", S60CertificateInfo::ProtServ },
65     { "ReadDeviceData", S60CertificateInfo::ReadDeviceData },
66     { "SurroundingsDD", S60CertificateInfo::SurroundingsDD },
67     { "SwEvent", S60CertificateInfo::SwEvent },
68     { "TrustedUI", S60CertificateInfo::TrustedUI },
69     { "WriteDeviceData", S60CertificateInfo::WriteDeviceData },
70     { "CommDD", S60CertificateInfo::CommDD },
71     { "DiskAdmin", S60CertificateInfo::DiskAdmin },
72     { "NetworkControl", S60CertificateInfo::NetworkControl },
73     { "MultimediaDD", S60CertificateInfo::MultimediaDD },
74     { "AllFiles", S60CertificateInfo::AllFiles },
75     { "DRM", S60CertificateInfo::DRM },
76     { "TCB", S60CertificateInfo::TCB }
77 };
78
79 struct CapabilitySet {
80     const char *color;
81     const int value;
82 };
83
84 static const CapabilitySet capabilitySet[] =
85 {
86     { "green", S60CertificateInfo::UserCapabilities },
87     { "darkorange", S60CertificateInfo::SystemCapabilities },
88     { "orangered", S60CertificateInfo::RestrictedCapabilities },
89     { "red", S60CertificateInfo::ManufacturerCapabilities }
90 };
91
92 QHash<int, QStringList> createCapabilityMap(uint capabilities)
93 {
94     const int capabilityCount = sizeof(capability)/sizeof(capability[0]);
95     const int capabilitySetCount = sizeof(capabilitySet)/sizeof(capabilitySet[0]);
96
97     QHash<int, QStringList> capabilityMap; //to separate the groups of capabilities
98     for(int i = 0; i < capabilityCount; ++i)
99         if (capabilities&capability[i].value) {
100             for (int j = 0; j < capabilitySetCount; ++j)
101                 if (capability[i].value&capabilitySet[j].value) {
102                     capabilityMap[capabilitySet[j].value] << capability[i].name;
103                     break;
104                 }
105         }
106
107     QMutableHashIterator<int, QStringList> i(capabilityMap);
108     while (i.hasNext()) {
109         i.next();
110         i.value().sort();
111     }
112
113     return capabilityMap;
114 }
115
116 QStringList createCapabilityList(uint capabilities)
117 {
118     QHash<int, QStringList> capabilityMap(createCapabilityMap(capabilities));
119
120     return capabilityMap[S60CertificateInfo::UserCapabilities]
121             + capabilityMap[S60CertificateInfo::SystemCapabilities]
122             + capabilityMap[S60CertificateInfo::RestrictedCapabilities]
123             + capabilityMap[S60CertificateInfo::ManufacturerCapabilities];
124 }
125
126 QStringList createHtmlCapabilityList(uint capabilities)
127 {
128     const int capabilitySetCount = sizeof(capabilitySet)/sizeof(capabilitySet[0]);
129     QHash<int, QStringList> capabilityMap(createCapabilityMap(capabilities));
130     QStringList result;
131
132     for (int j = 0; j < capabilitySetCount; ++j) {
133         QHashIterator<int, QStringList> i(capabilityMap);
134         while (i.hasNext()) {
135             i.next();
136             if (i.key() == capabilitySet[j].value) {
137                 foreach (const QString &capability, i.value()) {
138                     result << QString::fromAscii("<font color=\"%1\">%2</font>")
139                               .arg(capabilitySet[j].color).arg(capability);
140                 }
141                 break;
142             }
143         }
144     }
145     return result;
146 }
147
148 S60CertificateInfo::S60CertificateInfo(const QString &filePath, QObject* parent)
149     : QObject(parent),
150       m_certificate(new S60SymbianCertificate(filePath)),
151       m_filePath(filePath),
152       m_capabilities(NoInformation)
153 {
154     if (!m_certificate->isValid())
155         return;
156
157     m_imeiList = m_certificate->subjectInfo(QLatin1String("1.2.826.0.1.1796587.1.1.1.1"));
158
159     const QStringList capabilityList(m_certificate->subjectInfo(QLatin1String("1.2.826.0.1.1796587.1.1.1.6")));
160     if (capabilityList.isEmpty())
161         m_capabilities = 0;
162     else
163         m_capabilities = capabilityList.at(0).toLong();
164 }
165
166 S60CertificateInfo::~S60CertificateInfo()
167 {
168     delete m_certificate;
169 }
170
171 S60CertificateInfo::CertificateState S60CertificateInfo::validateCertificate()
172 {
173     CertificateState result = CertificateValid;
174     if (m_certificate->isValid()) {
175         QDateTime currentTime(QDateTime::currentDateTimeUtc());
176         QDateTime endTime(m_certificate->endTime());
177         QDateTime startTime(m_certificate->startTime());
178         if (currentTime > endTime) {
179             m_errorString = tr("The certificate \"%1\" has already expired and cannot be used."
180                                "\nExpiration date: %2.")
181                     .arg(QFileInfo(m_filePath).fileName())
182                     .arg(endTime.toLocalTime().toString(QLatin1String(SIMPLE_DATE_FORMAT)));
183             result = CertificateError;
184         } else if (currentTime < startTime) {
185             m_errorString = tr("The certificate \"%1\" is not yet valid.\nValid from: %2.")
186                     .arg(QFileInfo(m_filePath).fileName())
187                     .arg(startTime.toLocalTime().toString(QLatin1String(SIMPLE_DATE_FORMAT)));
188             result = CertificateWarning; //This certificate may be valid in the near future
189         }
190     } else {
191         m_errorString = tr("The certificate \"%1\" is not a valid X.509 certificate.")
192                 .arg(QFileInfo(m_filePath).baseName());
193         result = CertificateError;
194     }
195     return result;
196 }
197
198 bool S60CertificateInfo::compareCapabilities(const QStringList &givenCaps, QStringList &unsupportedCaps) const
199 {
200     if (!m_certificate->isValid())
201         return false;
202     unsupportedCaps.clear();
203     if (capabilitiesSupported() == NoInformation)
204         return true;
205
206     QStringList capabilities(createCapabilityList(capabilitiesSupported()));
207     foreach (const QString &capability, givenCaps) {
208         if (!capabilities.contains(capability, Qt::CaseInsensitive))
209             unsupportedCaps << capability;
210     }
211     return true;
212 }
213
214 QString S60CertificateInfo::errorString() const
215 {
216     return m_errorString.isEmpty()?m_certificate->errorString():m_errorString;
217 }
218
219 QStringList S60CertificateInfo::devicesSupported() const
220 {
221     return m_imeiList;
222 }
223
224 quint32 S60CertificateInfo::capabilitiesSupported() const
225 {
226     return m_capabilities;
227 }
228
229 bool S60CertificateInfo::isDeveloperCertificate() const
230 {
231     return !devicesSupported().isEmpty() || capabilitiesSupported();
232 }
233
234 QString S60CertificateInfo::toHtml(bool keepShort)
235 {
236     if (!m_certificate->isValid())
237         return errorString();
238
239     QString htmlString;
240     QTextStream str(&htmlString);
241     str << "<html><body><table>"
242         << "<tr><td><b>" << tr("Type: ") << "</b></td>";
243
244     if (isDeveloperCertificate())
245         str << "<td>" << tr("Developer certificate") << "</td>";
246     if (m_certificate->isSelfSigned())
247         str << "<td>" << tr("Self signed certificate") << "</td>";
248     str << "</tr>";
249
250     QString issuer;
251     QStringList issuerOrganizationList(m_certificate->issuerInfo("X520.Organization"));
252     if (!issuerOrganizationList.isEmpty())
253         issuer = issuerOrganizationList.join(QString(" "));
254
255     QString subject;
256     QStringList subjectOrganizationList(m_certificate->subjectInfo("X520.Organization"));
257     if (!subjectOrganizationList.isEmpty())
258         subject = subjectOrganizationList.join(QString(" "));
259
260     QDateTime startDate(m_certificate->startTime().toLocalTime());
261     QDateTime endDate(m_certificate->endTime().toLocalTime());
262
263     str << "<tr><td><b>" << tr("Issued by: ")
264         << "</b></td><td>" << issuer << "</td></tr>"
265         << "<tr><td><b>" << tr("Issued to: ")
266         << "</b></td><td>" << subject << "</td></tr>"
267         << "<tr><td><b>" << tr("Valid from: ")
268         << "</b></td><td>" << startDate.toString(QLatin1String(SIMPLE_DATE_FORMAT)) << "</td></tr>"
269         << "<tr><td><b>" << tr("Valid to: ")
270         << "</b></td><td>" << endDate.toString(QLatin1String(SIMPLE_DATE_FORMAT)) << "</td></tr>";
271
272     if (capabilitiesSupported()) {
273         QStringList capabilities;
274         if (keepShort)
275             capabilities = createCapabilityList(capabilitiesSupported());
276         else
277             capabilities = createHtmlCapabilityList(capabilitiesSupported());
278         str << "<tr><td><b>" << tr("Capabilities: ")
279             << "</b></td><td><i>" << capabilities.join(" ") << "</i></td></tr>";
280     }
281
282     const QStringList &imeiList(devicesSupported());
283     if (!imeiList.isEmpty()) {
284         QString imeiListString;
285         QString space(" ");
286         int MAX_DISPLAYED_IMEI_COUNT = 30;
287         if (imeiList.count() > MAX_DISPLAYED_IMEI_COUNT && keepShort) {//1000 items would be too much :)
288             for (int i = 0; i < MAX_DISPLAYED_IMEI_COUNT; ++i)
289                 imeiListString += imeiList.at(i) + space;
290             imeiListString.replace(imeiListString.length()-1, 1, QString("..."));
291         } else
292             imeiListString = imeiList.join(space);
293         str << "<tr><td><b>" << tr("Supporting %n device(s): ", "", imeiList.count())
294             << "</b></td><td>" << imeiListString << "</td></tr>";
295     }
296     return htmlString;
297 }