/************************************************************************** ** ** This file is part of Qt Creator ** ** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). ** ** Contact: Nokia Corporation (info@qt.nokia.com) ** ** ** GNU Lesser General Public License Usage ** ** This file may be used under the terms of the GNU Lesser General Public ** License version 2.1 as published by the Free Software Foundation and ** appearing in the file LICENSE.LGPL included in the packaging of this file. ** Please review the following information to ensure the GNU Lesser General ** Public License version 2.1 requirements will be met: ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** Other Usage ** ** Alternatively, this file may be used in accordance with the terms and ** conditions contained in a signed written agreement between you and Nokia. ** ** If you have questions regarding the use of this file, please contact ** Nokia at info@qt.nokia.com. ** **************************************************************************/ #include "s60certificateinfo.h" #include "s60symbiancertificate.h" #include #include #include #include #include #include using namespace Qt4ProjectManager; using namespace Qt4ProjectManager::Internal; namespace { const char * const SIMPLE_DATE_FORMAT = "dd.MM.yyyy"; } struct Capability { const char *name; const int value; }; static const Capability capability[] = { { "LocalServices", S60CertificateInfo::LocalServices }, { "Location", S60CertificateInfo::Location }, { "NetworkServices", S60CertificateInfo::NetworkServices }, { "ReadUserData", S60CertificateInfo::ReadUserData }, { "UserEnvironment", S60CertificateInfo::UserEnvironment }, { "WriteUserData", S60CertificateInfo::WriteUserData }, { "PowerMgmt", S60CertificateInfo::PowerMgmt }, { "ProtServ", S60CertificateInfo::ProtServ }, { "ReadDeviceData", S60CertificateInfo::ReadDeviceData }, { "SurroundingsDD", S60CertificateInfo::SurroundingsDD }, { "SwEvent", S60CertificateInfo::SwEvent }, { "TrustedUI", S60CertificateInfo::TrustedUI }, { "WriteDeviceData", S60CertificateInfo::WriteDeviceData }, { "CommDD", S60CertificateInfo::CommDD }, { "DiskAdmin", S60CertificateInfo::DiskAdmin }, { "NetworkControl", S60CertificateInfo::NetworkControl }, { "MultimediaDD", S60CertificateInfo::MultimediaDD }, { "AllFiles", S60CertificateInfo::AllFiles }, { "DRM", S60CertificateInfo::DRM }, { "TCB", S60CertificateInfo::TCB } }; struct CapabilitySet { const char *color; const int value; }; static const CapabilitySet capabilitySet[] = { { "green", S60CertificateInfo::UserCapabilities }, { "darkorange", S60CertificateInfo::SystemCapabilities }, { "orangered", S60CertificateInfo::RestrictedCapabilities }, { "red", S60CertificateInfo::ManufacturerCapabilities } }; QHash createCapabilityMap(uint capabilities) { const int capabilityCount = sizeof(capability)/sizeof(capability[0]); const int capabilitySetCount = sizeof(capabilitySet)/sizeof(capabilitySet[0]); QHash capabilityMap; //to separate the groups of capabilities for(int i = 0; i < capabilityCount; ++i) if (capabilities&capability[i].value) { for (int j = 0; j < capabilitySetCount; ++j) if (capability[i].value&capabilitySet[j].value) { capabilityMap[capabilitySet[j].value] << capability[i].name; break; } } QMutableHashIterator i(capabilityMap); while (i.hasNext()) { i.next(); i.value().sort(); } return capabilityMap; } QStringList createCapabilityList(uint capabilities) { QHash capabilityMap(createCapabilityMap(capabilities)); return capabilityMap[S60CertificateInfo::UserCapabilities] + capabilityMap[S60CertificateInfo::SystemCapabilities] + capabilityMap[S60CertificateInfo::RestrictedCapabilities] + capabilityMap[S60CertificateInfo::ManufacturerCapabilities]; } QStringList createHtmlCapabilityList(uint capabilities) { const int capabilitySetCount = sizeof(capabilitySet)/sizeof(capabilitySet[0]); QHash capabilityMap(createCapabilityMap(capabilities)); QStringList result; for (int j = 0; j < capabilitySetCount; ++j) { QHashIterator i(capabilityMap); while (i.hasNext()) { i.next(); if (i.key() == capabilitySet[j].value) { foreach (const QString &capability, i.value()) { result << QString::fromAscii("%2") .arg(capabilitySet[j].color).arg(capability); } break; } } } return result; } S60CertificateInfo::S60CertificateInfo(const QString &filePath, QObject* parent) : QObject(parent), m_certificate(new S60SymbianCertificate(filePath)), m_filePath(filePath), m_capabilities(NoInformation) { if (!m_certificate->isValid()) return; m_imeiList = m_certificate->subjectInfo(QLatin1String("1.2.826.0.1.1796587.1.1.1.1")); const QStringList capabilityList(m_certificate->subjectInfo(QLatin1String("1.2.826.0.1.1796587.1.1.1.6"))); if (capabilityList.isEmpty()) m_capabilities = 0; else m_capabilities = capabilityList.at(0).toLong(); } S60CertificateInfo::~S60CertificateInfo() { delete m_certificate; } S60CertificateInfo::CertificateState S60CertificateInfo::validateCertificate() { CertificateState result = CertificateValid; if (m_certificate->isValid()) { QDateTime currentTime(QDateTime::currentDateTimeUtc()); QDateTime endTime(m_certificate->endTime()); QDateTime startTime(m_certificate->startTime()); if (currentTime > endTime) { m_errorString = tr("The certificate \"%1\" has already expired and cannot be used." "\nExpiration date: %2.") .arg(QFileInfo(m_filePath).fileName()) .arg(endTime.toLocalTime().toString(QLatin1String(SIMPLE_DATE_FORMAT))); result = CertificateError; } else if (currentTime < startTime) { m_errorString = tr("The certificate \"%1\" is not yet valid.\nValid from: %2.") .arg(QFileInfo(m_filePath).fileName()) .arg(startTime.toLocalTime().toString(QLatin1String(SIMPLE_DATE_FORMAT))); result = CertificateWarning; //This certificate may be valid in the near future } } else { m_errorString = tr("The certificate \"%1\" is not a valid X.509 certificate.") .arg(QFileInfo(m_filePath).baseName()); result = CertificateError; } return result; } bool S60CertificateInfo::compareCapabilities(const QStringList &givenCaps, QStringList &unsupportedCaps) const { if (!m_certificate->isValid()) return false; unsupportedCaps.clear(); if (capabilitiesSupported() == NoInformation) return true; QStringList capabilities(createCapabilityList(capabilitiesSupported())); foreach (const QString &capability, givenCaps) { if (!capabilities.contains(capability, Qt::CaseInsensitive)) unsupportedCaps << capability; } return true; } QString S60CertificateInfo::errorString() const { return m_errorString.isEmpty()?m_certificate->errorString():m_errorString; } QStringList S60CertificateInfo::devicesSupported() const { return m_imeiList; } quint32 S60CertificateInfo::capabilitiesSupported() const { return m_capabilities; } bool S60CertificateInfo::isDeveloperCertificate() const { return !devicesSupported().isEmpty() || capabilitiesSupported(); } QString S60CertificateInfo::toHtml(bool keepShort) { if (!m_certificate->isValid()) return errorString(); QString htmlString; QTextStream str(&htmlString); str << "" << ""; if (isDeveloperCertificate()) str << ""; if (m_certificate->isSelfSigned()) str << ""; str << ""; QString issuer; QStringList issuerOrganizationList(m_certificate->issuerInfo("X520.Organization")); if (!issuerOrganizationList.isEmpty()) issuer = issuerOrganizationList.join(QString(" ")); QString subject; QStringList subjectOrganizationList(m_certificate->subjectInfo("X520.Organization")); if (!subjectOrganizationList.isEmpty()) subject = subjectOrganizationList.join(QString(" ")); QDateTime startDate(m_certificate->startTime().toLocalTime()); QDateTime endDate(m_certificate->endTime().toLocalTime()); str << "" << "" << "" << ""; if (capabilitiesSupported()) { QStringList capabilities; if (keepShort) capabilities = createCapabilityList(capabilitiesSupported()); else capabilities = createHtmlCapabilityList(capabilitiesSupported()); str << ""; } const QStringList &imeiList(devicesSupported()); if (!imeiList.isEmpty()) { QString imeiListString; QString space(" "); int MAX_DISPLAYED_IMEI_COUNT = 30; if (imeiList.count() > MAX_DISPLAYED_IMEI_COUNT && keepShort) {//1000 items would be too much :) for (int i = 0; i < MAX_DISPLAYED_IMEI_COUNT; ++i) imeiListString += imeiList.at(i) + space; imeiListString.replace(imeiListString.length()-1, 1, QString("...")); } else imeiListString = imeiList.join(space); str << ""; } return htmlString; }
" << tr("Type: ") << "" << tr("Developer certificate") << "" << tr("Self signed certificate") << "
" << tr("Issued by: ") << "" << issuer << "
" << tr("Issued to: ") << "" << subject << "
" << tr("Valid from: ") << "" << startDate.toString(QLatin1String(SIMPLE_DATE_FORMAT)) << "
" << tr("Valid to: ") << "" << endDate.toString(QLatin1String(SIMPLE_DATE_FORMAT)) << "
" << tr("Capabilities: ") << "" << capabilities.join(" ") << "
" << tr("Supporting %n device(s): ", "", imeiList.count()) << "" << imeiListString << "