OSDN Git Service

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