forked from qt-creator/qt-creator
Capabilities and IMEIs can now be extracted form Dev Certs for SymbianOS
Reviewed-by: Alessandro Portale
This commit is contained in:
@@ -40,7 +40,16 @@ CertificatePathChooser::CertificatePathChooser(QWidget *parent) :
|
|||||||
|
|
||||||
bool CertificatePathChooser::validatePath(const QString &path, QString *errorMessage)
|
bool CertificatePathChooser::validatePath(const QString &path, QString *errorMessage)
|
||||||
{
|
{
|
||||||
if (Utils::PathChooser::validatePath(path, errorMessage))
|
if (Utils::PathChooser::validatePath(path, errorMessage)) {
|
||||||
return S60CertificateInfo::validateCertificate(path, errorMessage) == S60CertificateInfo::CertificateValid;
|
QScopedPointer<S60CertificateInfo> certInfoPtr(new S60CertificateInfo(path));
|
||||||
|
if (certInfoPtr.data()->validateCertificate() == S60CertificateInfo::CertificateValid) {
|
||||||
|
if (errorMessage)
|
||||||
|
*errorMessage = certInfoPtr.data()->toHtml();
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
if (errorMessage)
|
||||||
|
*errorMessage = certInfoPtr.data()->errorString();
|
||||||
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,42 +32,161 @@
|
|||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
|
#include <QTextStream>
|
||||||
|
|
||||||
#include "s60symbiancertificate.h"
|
#include "s60symbiancertificate.h"
|
||||||
|
|
||||||
S60CertificateInfo::CertificateState S60CertificateInfo::validateCertificate(const QString &certFilePath, QString *errorString)
|
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 }
|
||||||
|
};
|
||||||
|
|
||||||
|
QStringList createCapabilityList(uint capabilities)
|
||||||
|
{
|
||||||
|
const int capabilityCount = sizeof(capability)/sizeof(capability[0]);
|
||||||
|
QStringList capabilityList;
|
||||||
|
for(int i = 0; i < capabilityCount; ++i)
|
||||||
|
if (capabilities&capability[i].value)
|
||||||
|
capabilityList << QLatin1String(capability[i].name);
|
||||||
|
return capabilityList;
|
||||||
|
}
|
||||||
|
|
||||||
|
S60CertificateInfo::S60CertificateInfo(const QString &filePath, QObject* parent)
|
||||||
|
: QObject(parent),
|
||||||
|
m_certificate(new S60SymbianCertificate(filePath)),
|
||||||
|
m_filePath(filePath)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
S60CertificateInfo::~S60CertificateInfo()
|
||||||
|
{
|
||||||
|
delete m_certificate;
|
||||||
|
}
|
||||||
|
|
||||||
|
S60CertificateInfo::CertificateState S60CertificateInfo::validateCertificate()
|
||||||
{
|
{
|
||||||
CertificateState result = CertificateValid;
|
CertificateState result = CertificateValid;
|
||||||
S60SymbianCertificate *certificate = new S60SymbianCertificate(certFilePath);
|
if (m_certificate->isValid()) {
|
||||||
if (certificate->isValid()) {
|
|
||||||
QDateTime currentTime(QDateTime::currentDateTimeUtc());
|
QDateTime currentTime(QDateTime::currentDateTimeUtc());
|
||||||
QDateTime endTime(certificate->endTime());
|
QDateTime endTime(m_certificate->endTime());
|
||||||
QDateTime startTime(certificate->startTime());
|
QDateTime startTime(m_certificate->startTime());
|
||||||
if (currentTime > endTime) {
|
if (currentTime > endTime) {
|
||||||
if (errorString)
|
m_errorString = tr("The \"%1\" certificate has already expired and cannot be used."
|
||||||
*errorString = QCoreApplication::translate(
|
"\nExpiration date: %2.")
|
||||||
"S60Utils::validateCertificate",
|
.arg(QFileInfo(m_filePath).fileName())
|
||||||
"The \"%1\" certificate has already expired and cannot be used.\nExpiration date: %2.")
|
.arg(endTime.toLocalTime().toString(QLatin1String(SIMPLE_DATE_FORMAT)));
|
||||||
.arg(QFileInfo(certFilePath).fileName())
|
|
||||||
.arg(endTime.toLocalTime().toString());
|
|
||||||
result = CertificateError;
|
result = CertificateError;
|
||||||
} else if (currentTime < startTime) {
|
} else if (currentTime < startTime) {
|
||||||
if (errorString)
|
m_errorString = tr("The \"%1\" certificate is not yet valid.\nValid from: %2.")
|
||||||
*errorString = QCoreApplication::translate(
|
.arg(QFileInfo(m_filePath).fileName())
|
||||||
"S60Utils::validateCertificate",
|
.arg(startTime.toLocalTime().toString(QLatin1String(SIMPLE_DATE_FORMAT)));
|
||||||
"The \"%1\" certificate is not yet valid.\nValid from: %2.")
|
|
||||||
.arg(QFileInfo(certFilePath).fileName())
|
|
||||||
.arg(startTime.toLocalTime().toString());
|
|
||||||
result = CertificateWarning; //This certificate may be valid in the near future
|
result = CertificateWarning; //This certificate may be valid in the near future
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (errorString)
|
m_errorString = tr("The \"%1\" certificate is not a valid X.509 certificate.")
|
||||||
*errorString = QCoreApplication::translate(
|
.arg(QFileInfo(m_filePath).baseName());
|
||||||
"S60Utils::validateCertificate",
|
|
||||||
"The \"%1\" certificate is not a valid X.509 certificate.")
|
|
||||||
.arg(QFileInfo(certFilePath).baseName());
|
|
||||||
result = CertificateError;
|
result = CertificateError;
|
||||||
}
|
}
|
||||||
delete certificate;
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString S60CertificateInfo::errorString() const
|
||||||
|
{
|
||||||
|
return m_errorString.isEmpty()?m_certificate->errorString():m_errorString;
|
||||||
|
}
|
||||||
|
|
||||||
|
quint32 S60CertificateInfo::capabilitiesSupported()
|
||||||
|
{
|
||||||
|
return NoInformation;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString S60CertificateInfo::toHtml()
|
||||||
|
{
|
||||||
|
const QStringList capabilityList(m_certificate->subjectInfo(QLatin1String("1.2.826.0.1.1796587.1.1.1.6")));
|
||||||
|
|
||||||
|
QString htmlString;
|
||||||
|
QTextStream str(&htmlString);
|
||||||
|
str << "<html><body><table>"
|
||||||
|
<< "<tr><td><b>" << tr("Type: ") << "</b></td>";
|
||||||
|
|
||||||
|
if (!capabilityList.isEmpty())
|
||||||
|
str << "<td>" << tr("Developer certificate") << "</td>";
|
||||||
|
if (m_certificate->isSelfSigned())
|
||||||
|
str << "<td>" << tr("Self signed certificate") << "</td>";
|
||||||
|
str << "</tr>";
|
||||||
|
|
||||||
|
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 << "<tr><td><b>" << tr("Issued by: ")
|
||||||
|
<< "</b></td><td>" << issuer << "</td></tr>"
|
||||||
|
<< "<tr><td><b>" << tr("Issued to: ")
|
||||||
|
<< "</b></td><td>" << subject << "</td></tr>"
|
||||||
|
<< "<tr><td><b>" << tr("Valid from: ")
|
||||||
|
<< "</b></td><td>" << startDate.toString(QLatin1String(SIMPLE_DATE_FORMAT)) << "</td></tr>"
|
||||||
|
<< "<tr><td><b>" << tr("Valid to: ")
|
||||||
|
<< "</b></td><td>" << endDate.toString(QLatin1String(SIMPLE_DATE_FORMAT)) << "</td></tr>";
|
||||||
|
|
||||||
|
if (!capabilityList.isEmpty()) {
|
||||||
|
bool isOk(false);
|
||||||
|
quint32 capabilities = capabilityList.at(0).toLong(&isOk);
|
||||||
|
if (isOk) {
|
||||||
|
str << "<tr><td><b>" << tr("Capabilities: ")
|
||||||
|
<< "</b></td><td>" << createCapabilityList(capabilities).join(" ") << "</td></tr>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const QStringList imeiList(m_certificate->subjectInfo(QLatin1String("1.2.826.0.1.1796587.1.1.1.1")));
|
||||||
|
if (!imeiList.isEmpty()) {
|
||||||
|
QString imeiListString;
|
||||||
|
QString space(" ");
|
||||||
|
int MAX_DISPLAYED_IMEI_COUNT = 30;
|
||||||
|
if (imeiList.count() > MAX_DISPLAYED_IMEI_COUNT) {//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 << "<tr><td><b>" << tr("Supporting %n device(s): ", "", imeiList.count())
|
||||||
|
<< "</b></td><td>" << imeiListString << "</td></tr>";
|
||||||
|
}
|
||||||
|
return htmlString;
|
||||||
|
}
|
||||||
|
|||||||
@@ -30,19 +30,60 @@
|
|||||||
#ifndef S60CERTIFICATEINFO_H
|
#ifndef S60CERTIFICATEINFO_H
|
||||||
#define S60CERTIFICATEINFO_H
|
#define S60CERTIFICATEINFO_H
|
||||||
|
|
||||||
|
#include <QtCore/QObject>
|
||||||
#include <QtCore/QtGlobal>
|
#include <QtCore/QtGlobal>
|
||||||
|
|
||||||
QT_FORWARD_DECLARE_CLASS(QString)
|
QT_FORWARD_DECLARE_CLASS(QString)
|
||||||
|
QT_FORWARD_DECLARE_CLASS(S60SymbianCertificate)
|
||||||
|
|
||||||
class S60CertificateInfo
|
class S60CertificateInfo : public QObject
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum CertificateState {
|
enum CertificateState {
|
||||||
CertificateValid,
|
CertificateValid,
|
||||||
CertificateWarning,
|
CertificateWarning,
|
||||||
CertificateError
|
CertificateError
|
||||||
};
|
};
|
||||||
static CertificateState validateCertificate(const QString &certFilePath, QString *errorString = 0);
|
|
||||||
|
enum S60Capability {
|
||||||
|
TCB = 1 << (31-0),
|
||||||
|
CommDD = 1 << (31-1),
|
||||||
|
PowerMgmt = 1 << (31-2),
|
||||||
|
MultimediaDD = 1 << (31-3),
|
||||||
|
ReadDeviceData = 1 << (31-4),
|
||||||
|
WriteDeviceData = 1 << (31-5),
|
||||||
|
DRM = 1 << (31-6),
|
||||||
|
TrustedUI = 1 << (31-7),
|
||||||
|
ProtServ = 1 << (31-8),
|
||||||
|
DiskAdmin = 1 << (31-9),
|
||||||
|
NetworkControl = 1 << (31-10),
|
||||||
|
AllFiles = 1 << (31-11),
|
||||||
|
SwEvent = 1 << (31-12),
|
||||||
|
NetworkServices = 1 << (31-13),
|
||||||
|
LocalServices = 1 << (31-14),
|
||||||
|
ReadUserData = 1 << (31-15),
|
||||||
|
WriteUserData = 1 << (31-16),
|
||||||
|
Location = 1 << (31-17),
|
||||||
|
SurroundingsDD = 1 << (31-18),
|
||||||
|
UserEnvironment = 1 << (31-19),
|
||||||
|
|
||||||
|
NoInformation = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
explicit S60CertificateInfo(const QString &filePath, QObject* parent = 0);
|
||||||
|
~S60CertificateInfo();
|
||||||
|
|
||||||
|
CertificateState validateCertificate();
|
||||||
|
quint32 capabilitiesSupported();
|
||||||
|
QString toHtml();
|
||||||
|
QString errorString() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
S60SymbianCertificate *m_certificate;
|
||||||
|
QString m_filePath;
|
||||||
|
QString m_errorString;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // S60CERTIFICATEINFO_H
|
#endif // S60CERTIFICATEINFO_H
|
||||||
|
|||||||
@@ -469,20 +469,20 @@ bool S60CreatePackageStep::validateCustomSigningResources()
|
|||||||
ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM));
|
ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
QScopedPointer<S60CertificateInfo> certInfoPtr(new S60CertificateInfo(customSignaturePath()));
|
||||||
S60CertificateInfo::CertificateState certState = S60CertificateInfo::validateCertificate(customSignaturePath(), &errorString);
|
S60CertificateInfo::CertificateState certState = certInfoPtr.data()->validateCertificate();
|
||||||
switch (certState) {
|
switch (certState) {
|
||||||
case S60CertificateInfo::CertificateError:
|
case S60CertificateInfo::CertificateError:
|
||||||
emit addOutput(errorString, BuildStep::ErrorMessageOutput);
|
emit addOutput(certInfoPtr.data()->errorString(), BuildStep::ErrorMessageOutput);
|
||||||
emit addTask(ProjectExplorer::Task(ProjectExplorer::Task::Error,
|
emit addTask(ProjectExplorer::Task(ProjectExplorer::Task::Error,
|
||||||
errorString,
|
certInfoPtr.data()->errorString(),
|
||||||
QString(), -1,
|
QString(), -1,
|
||||||
ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM));
|
ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM));
|
||||||
return false;
|
return false;
|
||||||
case S60CertificateInfo::CertificateWarning:
|
case S60CertificateInfo::CertificateWarning:
|
||||||
emit addOutput(errorString, BuildStep::MessageOutput);
|
emit addOutput(certInfoPtr.data()->errorString(), BuildStep::MessageOutput);
|
||||||
emit addTask(ProjectExplorer::Task(ProjectExplorer::Task::Warning,
|
emit addTask(ProjectExplorer::Task(ProjectExplorer::Task::Warning,
|
||||||
errorString,
|
certInfoPtr.data()->errorString(),
|
||||||
QString(), -1,
|
QString(), -1,
|
||||||
ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM));
|
ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM));
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -38,10 +38,275 @@
|
|||||||
#include <botan/bigint.h>
|
#include <botan/bigint.h>
|
||||||
#include <botan/oids.h>
|
#include <botan/oids.h>
|
||||||
#include <botan/pem.h>
|
#include <botan/pem.h>
|
||||||
|
#include <botan/sha160.h>
|
||||||
|
#include <botan/oids.h>
|
||||||
|
#include <botan/libstate.h>
|
||||||
|
#include <botan/bit_ops.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
using namespace Botan;
|
using namespace Botan;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
const char * const CERT_IMEI_FIELD_NAME = "1.2.826.0.1.1796587.1.1.1.1";
|
||||||
|
const char * const CERT_CAPABILITY_FIELD_NAME = "1.2.826.0.1.1796587.1.1.1.6";
|
||||||
|
}
|
||||||
|
|
||||||
|
// ======== S60CertificateExtension
|
||||||
|
|
||||||
|
/*
|
||||||
|
* X.509 S60 Certificate Extension
|
||||||
|
*/
|
||||||
|
class S60CertificateExtension : Certificate_Extension
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
OID oid_of() const;
|
||||||
|
|
||||||
|
virtual S60CertificateExtension* copy() const = 0;
|
||||||
|
virtual ~S60CertificateExtension() {}
|
||||||
|
protected:
|
||||||
|
friend class S60Extensions;
|
||||||
|
virtual bool should_encode() const { return false; }
|
||||||
|
virtual MemoryVector<byte> encode_inner() const = 0;
|
||||||
|
virtual void decode_inner(const MemoryRegion<byte>&) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======== S60DeviceIdListConstraint
|
||||||
|
|
||||||
|
class S60DeviceIdListConstraint : public S60CertificateExtension
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
S60CertificateExtension* copy() const { return new S60DeviceIdListConstraint(imei_list); }
|
||||||
|
|
||||||
|
S60DeviceIdListConstraint() {}
|
||||||
|
S60DeviceIdListConstraint(const std::vector<ASN1_String>& o) : imei_list(o) {}
|
||||||
|
|
||||||
|
std::vector<ASN1_String> get_imei_list() const { return imei_list; }
|
||||||
|
private:
|
||||||
|
std::string config_id() const { return "deviceid_list_constraint"; }
|
||||||
|
std::string oid_name() const { return CERT_IMEI_FIELD_NAME; }
|
||||||
|
|
||||||
|
MemoryVector<byte> encode_inner() const;
|
||||||
|
void decode_inner(const MemoryRegion<byte>&);
|
||||||
|
void contents_to(Data_Store&, Data_Store&) const;
|
||||||
|
|
||||||
|
std::vector<ASN1_String> imei_list;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Encode the extension
|
||||||
|
*/
|
||||||
|
MemoryVector<byte> S60DeviceIdListConstraint::encode_inner() const
|
||||||
|
{
|
||||||
|
qFatal("Encoding S60 extensions is not supported.");
|
||||||
|
return MemoryVector<byte>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Decode the extension
|
||||||
|
*/
|
||||||
|
#include "botan/hex.h"
|
||||||
|
void S60DeviceIdListConstraint::decode_inner(const MemoryRegion<byte>& in)
|
||||||
|
{
|
||||||
|
BER_Decoder(in)
|
||||||
|
.start_cons(SEQUENCE)
|
||||||
|
.decode_list(imei_list)
|
||||||
|
.end_cons();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return a textual representation
|
||||||
|
*/
|
||||||
|
void S60DeviceIdListConstraint::contents_to(Data_Store& subject, Data_Store&) const
|
||||||
|
{
|
||||||
|
for(u32bit j = 0; j != imei_list.size(); ++j)
|
||||||
|
subject.add(CERT_IMEI_FIELD_NAME, imei_list[j].value());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ======== S60CapabilityConstraint
|
||||||
|
|
||||||
|
class S60CapabilityConstraint : public S60CertificateExtension
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
S60CertificateExtension* copy() const { return new S60CapabilityConstraint(capabilities); }
|
||||||
|
|
||||||
|
S60CapabilityConstraint() {}
|
||||||
|
S60CapabilityConstraint(const SecureVector<byte>& o) : capabilities(o) {}
|
||||||
|
|
||||||
|
SecureVector<byte> get_capability_list() const { return capabilities; }
|
||||||
|
private:
|
||||||
|
std::string config_id() const { return "capability_constraint"; }
|
||||||
|
std::string oid_name() const { return "CERT_CAPABILITY_FIELD_NAME"; }
|
||||||
|
|
||||||
|
MemoryVector<byte> encode_inner() const;
|
||||||
|
void decode_inner(const MemoryRegion<byte>&);
|
||||||
|
void contents_to(Data_Store&, Data_Store&) const;
|
||||||
|
|
||||||
|
SecureVector<byte> capabilities;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Encode the extension
|
||||||
|
*/
|
||||||
|
MemoryVector<byte> S60CapabilityConstraint::encode_inner() const
|
||||||
|
{
|
||||||
|
qFatal("Encoding S60 extensions is not supported.");
|
||||||
|
return MemoryVector<byte>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Decode the extension
|
||||||
|
*/
|
||||||
|
void S60CapabilityConstraint::decode_inner(const MemoryRegion<byte>& in)
|
||||||
|
{
|
||||||
|
BER_Decoder(in)
|
||||||
|
.decode(capabilities, BIT_STRING)
|
||||||
|
.verify_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return a textual representation
|
||||||
|
*/
|
||||||
|
void S60CapabilityConstraint::contents_to(Data_Store& subject, Data_Store&) const
|
||||||
|
{
|
||||||
|
quint32 capabilitiesValue = 0;
|
||||||
|
for(u32bit j = 0; j != sizeof(quint32); ++j) {
|
||||||
|
quint32 capabilitie(capabilities[sizeof(quint32)-1-j]);
|
||||||
|
capabilitiesValue |= capabilitie << 8*j;
|
||||||
|
}
|
||||||
|
subject.add(CERT_CAPABILITY_FIELD_NAME, capabilitiesValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ======== S60Extensions
|
||||||
|
|
||||||
|
class S60Extensions : public ASN1_Object
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void encode_into(class DER_Encoder&) const;
|
||||||
|
void decode_from(class BER_Decoder&);
|
||||||
|
|
||||||
|
void contents_to(Data_Store&, Data_Store&) const;
|
||||||
|
|
||||||
|
void add(Certificate_Extension* extn)
|
||||||
|
{ extensions.push_back(extn); }
|
||||||
|
|
||||||
|
S60Extensions& operator=(const S60Extensions&);
|
||||||
|
|
||||||
|
S60Extensions(const S60Extensions&);
|
||||||
|
S60Extensions(bool st = true) : should_throw(st) {}
|
||||||
|
~S60Extensions();
|
||||||
|
private:
|
||||||
|
static Certificate_Extension* get_extension(const OID&);
|
||||||
|
|
||||||
|
std::vector<Certificate_Extension*> extensions;
|
||||||
|
bool should_throw;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* S60Extensions Copy Constructor
|
||||||
|
*/
|
||||||
|
S60Extensions::S60Extensions(const S60Extensions& extensions) : ASN1_Object()
|
||||||
|
{
|
||||||
|
*this = extensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extensions Assignment Operator
|
||||||
|
*/
|
||||||
|
S60Extensions& S60Extensions::operator=(const S60Extensions& other)
|
||||||
|
{
|
||||||
|
for(u32bit j = 0; j != extensions.size(); ++j)
|
||||||
|
delete extensions[j];
|
||||||
|
extensions.clear();
|
||||||
|
|
||||||
|
for(u32bit j = 0; j != other.extensions.size(); ++j)
|
||||||
|
extensions.push_back(other.extensions[j]->copy());
|
||||||
|
|
||||||
|
return (*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the OID of this extension
|
||||||
|
*/
|
||||||
|
OID Certificate_Extension::oid_of() const
|
||||||
|
{
|
||||||
|
return OIDS::lookup(oid_name());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Encode an Extensions list
|
||||||
|
*/
|
||||||
|
void S60Extensions::encode_into(DER_Encoder& to_object) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(to_object);
|
||||||
|
qFatal("Encoding S60 extensions is not supported.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Decode a list of Extensions
|
||||||
|
*/
|
||||||
|
void S60Extensions::decode_from(BER_Decoder& from_source)
|
||||||
|
{
|
||||||
|
for(u32bit j = 0; j != extensions.size(); ++j)
|
||||||
|
delete extensions[j];
|
||||||
|
extensions.clear();
|
||||||
|
|
||||||
|
BER_Decoder sequence = from_source.start_cons(SEQUENCE);
|
||||||
|
while(sequence.more_items())
|
||||||
|
{
|
||||||
|
OID oid;
|
||||||
|
MemoryVector<byte> value;
|
||||||
|
bool critical;
|
||||||
|
|
||||||
|
sequence.start_cons(SEQUENCE)
|
||||||
|
.decode(oid)
|
||||||
|
.decode_optional(critical, BOOLEAN, UNIVERSAL, false)
|
||||||
|
.decode(value, OCTET_STRING)
|
||||||
|
.verify_end()
|
||||||
|
.end_cons();
|
||||||
|
|
||||||
|
S60CertificateExtension* ext = 0;
|
||||||
|
if (OIDS::name_of(oid, CERT_IMEI_FIELD_NAME))
|
||||||
|
ext = new S60DeviceIdListConstraint();
|
||||||
|
|
||||||
|
if (OIDS::name_of(oid, CERT_CAPABILITY_FIELD_NAME))
|
||||||
|
ext = new S60CapabilityConstraint();
|
||||||
|
|
||||||
|
if(!ext)
|
||||||
|
{
|
||||||
|
if(!critical || !should_throw)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
throw Decoding_Error("Encountered unknown X.509 extension marked "
|
||||||
|
"as critical; OID = " + oid.as_string());
|
||||||
|
}
|
||||||
|
ext->decode_inner(value);
|
||||||
|
extensions.push_back(ext);
|
||||||
|
}
|
||||||
|
sequence.verify_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write the extensions to an info store
|
||||||
|
*/
|
||||||
|
void S60Extensions::contents_to(Data_Store& subject_info,
|
||||||
|
Data_Store& issuer_info) const
|
||||||
|
{
|
||||||
|
for(u32bit j = 0; j != extensions.size(); ++j)
|
||||||
|
extensions[j]->contents_to(subject_info, issuer_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Delete an Extensions list
|
||||||
|
*/
|
||||||
|
S60Extensions::~S60Extensions()
|
||||||
|
{
|
||||||
|
for(u32bit j = 0; j != extensions.size(); ++j)
|
||||||
|
delete extensions[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ======== S60SymbianCertificatePrivate
|
// ======== S60SymbianCertificatePrivate
|
||||||
|
|
||||||
class S60SymbianCertificatePrivate : private Botan::X509_Object
|
class S60SymbianCertificatePrivate : private Botan::X509_Object
|
||||||
@@ -242,6 +507,12 @@ void S60SymbianCertificatePrivate::force_decode()
|
|||||||
if(v3_exts_data.type_tag == 3 &&
|
if(v3_exts_data.type_tag == 3 &&
|
||||||
v3_exts_data.class_tag == ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC))
|
v3_exts_data.class_tag == ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC))
|
||||||
{
|
{
|
||||||
|
S60Extensions s60extensions(false);
|
||||||
|
|
||||||
|
BER_Decoder(v3_exts_data.value).decode(s60extensions).verify_end();
|
||||||
|
|
||||||
|
s60extensions.contents_to(m_subject, m_issuer);
|
||||||
|
|
||||||
Extensions extensions(false);
|
Extensions extensions(false);
|
||||||
|
|
||||||
BER_Decoder(v3_exts_data.value).decode(extensions).verify_end();
|
BER_Decoder(v3_exts_data.value).decode(extensions).verify_end();
|
||||||
@@ -458,7 +729,6 @@ AlternativeName create_alt_name(const Data_Store& info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ======== S60SymbianCertificate
|
// ======== S60SymbianCertificate
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
S60SymbianCertificate::S60SymbianCertificate(const QString &filename) : m_d(0)
|
S60SymbianCertificate::S60SymbianCertificate(const QString &filename) : m_d(0)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user