794
802
else if(in[n] == ',')
804
else if(in[n] == '\n')
802
static QString unescape_string(const QString &in)
812
static bool unescape_string(const QString &in, QString *_out)
805
815
for(int n = 0; n < in.length(); ++n)
807
817
if(in[n] == '\\')
809
if(n + 1 < in.length())
811
if(in[n + 1] == '\\')
813
else if(in[n + 1] == 'c')
815
else if(in[n + 1] == 'o')
819
if(n + 1 >= in.length())
822
if(in[n + 1] == '\\')
824
else if(in[n + 1] == 'c')
826
else if(in[n + 1] == 'o')
828
else if(in[n + 1] == 'n')
826
static QString makeId(const QString &storeId, const QString &storeName, const QString &entryId, const QString &entryName, const QString &entryType, const QString &pem)
841
static QString escape_stringlist(const QStringList &in)
844
for(int n = 0; n < in.count(); ++n)
845
list += escape_string(in[n]);
846
return list.join(":");
849
static bool unescape_stringlist(const QString &in, QStringList *_out)
829
out += escape_string("qca_def");
830
out += escape_string(storeId);
831
out += escape_string(storeName);
832
out += escape_string(entryId);
833
out += escape_string(entryName);
834
out += escape_string(entryType);
835
out += escape_string(pem);
836
return out.join(":");
839
static bool parseId(const QString &in, QString *storeId, QString *storeName, QString *entryId, QString *entryName, QString *entryType, QString *pem)
841
852
QStringList list = in.split(':');
853
for(int n = 0; n < list.count(); ++n)
856
if(!unescape_string(list[n], &str))
864
// serialization format is a colon separated list of 7 escaped strings
865
// 0 - "qca_def_1" (header)
870
// 5 - entry type (e.g. "cert")
871
// 6 - string encoding of object (e.g. DER encoded in Base64)
872
static QString entry_serialize(const QString &storeId, const QString &storeName, const QString &entryId, const QString &entryName, const QString &entryType, const QString &data)
882
return escape_stringlist(out);
885
static bool entry_deserialize(const QString &in, QString *storeId, QString *storeName, QString *entryId, QString *entryName, QString *entryType, QString *data)
888
if(!unescape_stringlist(in, &list))
842
890
if(list.count() != 7)
844
QString header = unescape_string(list[0]);
845
if(header != "qca_def")
892
if(list[0] != "qca_def")
847
*storeId = unescape_string(list[1]);
848
*storeName = unescape_string(list[2]);
849
*entryId = unescape_string(list[3]);
850
*entryName = unescape_string(list[4]);
851
*entryType = unescape_string(list[5]);
852
*pem = unescape_string(list[6]);
895
*storeName = list[2];
897
*entryName = list[4];
898
*entryType = list[5];
856
903
class DefaultKeyStoreEntry : public KeyStoreEntryContext
859
KeyStoreEntry::Type item_type;
860
QString item_id, _storeId, _storeName;
906
KeyStoreEntry::Type _type;
907
QString _id, _name, _storeId, _storeName;
861
908
Certificate _cert;
910
mutable QString _serialized;
867
912
DefaultKeyStoreEntry(const Certificate &cert, const QString &storeId, const QString &storeName, Provider *p) : KeyStoreEntryContext(p)
914
_type = KeyStoreEntry::TypeCertificate;
869
915
_storeId = storeId;
870
916
_storeName = storeName;
872
item_type = KeyStoreEntry::TypeCertificate;
875
920
DefaultKeyStoreEntry(const CRL &crl, const QString &storeId, const QString &storeName, Provider *p) : KeyStoreEntryContext(p)
922
_type = KeyStoreEntry::TypeCRL;
877
923
_storeId = storeId;
878
924
_storeName = storeName;
880
item_type = KeyStoreEntry::TypeCRL;
883
DefaultKeyStoreEntry(const DefaultKeyStoreEntry &from) : KeyStoreEntryContext(from)
887
~DefaultKeyStoreEntry()
891
928
virtual Provider::Context *clone() const
945
968
virtual QString serialize() const
970
if(_serialized.isEmpty())
975
if(_type == KeyStoreEntry::TypeCertificate)
978
datastr = Base64().arrayToString(_cert.toDER());
983
datastr = Base64().arrayToString(_crl.toDER());
986
_serialized = entry_serialize(_storeId, _storeName, _id, _name, typestr, datastr);
992
static DefaultKeyStoreEntry *deserialize(const QString &in, Provider *provider)
994
QString storeId, storeName, id, name, typestr, datastr;
996
if(entry_deserialize(in, &storeId, &storeName, &id, &name, &typestr, &datastr))
998
QByteArray data = Base64().stringToArray(datastr).toByteArray();
999
DefaultKeyStoreEntry *c;
1001
if(typestr == "cert")
1003
Certificate cert = Certificate::fromDER(data);
1006
c = new DefaultKeyStoreEntry(cert, storeId, storeName, provider);
1008
else if(typestr == "crl")
1010
CRL crl = CRL::fromDER(data);
1013
c = new DefaultKeyStoreEntry(crl, storeId, storeName, provider);
1020
c->_serialized = in;
1026
QString simpleId() const
1028
if(_type == KeyStoreEntry::TypeCertificate)
1029
return QString::number(qHash(_cert.toDER()));
1031
return QString::number(qHash(_crl.toDER()));
1034
QString simpleName() const
1036
// use the common name, else orgname
1037
if(_type == KeyStoreEntry::TypeCertificate)
1039
QString str = _cert.commonName();
1041
str = _cert.subjectInfo().value(Organization);
1045
return _crl.issuerInfo().value(CommonName);
974
1072
virtual void start()
1074
x509_supported = false;
978
#ifndef QCA_NO_SYSTEMSTORE
979
if(qca_have_systemstore() &&
980
isSupported("cert") &&
986
1076
QMetaObject::invokeMethod(this, "busyEnd", Qt::QueuedConnection);
989
1079
virtual QList<int> keyStores()
1083
if(isSupported("cert") && isSupported("crl"))
1084
x509_supported = true;
1087
bool have_systemstore = false;
1088
#ifndef QCA_NO_SYSTEMSTORE
1089
if(shared->use_system())
1090
have_systemstore = qca_have_systemstore();
991
1093
QList<int> list;
992
if(ready || !shared->roots_file().isEmpty())
1095
// system store only shows up if the OS store is available or
1096
// there is a configured store file
1097
if(x509_supported && (have_systemstore || !shared->roots_file().isEmpty()))
1042
1148
crls += col.crls();
1045
//QStringList names = makeFriendlyNames(certs);
1047
for(n = 0; n < certs.count(); ++n)
1151
#ifdef FRIENDLY_NAMES
1152
QStringList names = makeFriendlyNames(certs);
1154
for(int n = 0; n < certs.count(); ++n)
1049
1156
DefaultKeyStoreEntry *c = new DefaultKeyStoreEntry(certs[n], storeId(0), name(0), provider());
1050
//c->item_id = QString::number(n);
1051
QString ename = c->makeName();
1052
//QString ename = names[n];
1053
QString eid = QString::number(qHash(certs[n].toDER()));
1054
c->item_name = ename;
1056
c->item_save = makeId(storeId(0), name(0), eid, ename, "cert", certs[n].toPEM());
1157
c->_id = c->simpleId();
1158
#ifdef FRIENDLY_NAMES
1159
c->_name = names[n];
1161
c->_name = c->simpleName();
1059
for(n = 0; n < crls.count(); ++n)
1166
for(int n = 0; n < crls.count(); ++n)
1061
1168
DefaultKeyStoreEntry *c = new DefaultKeyStoreEntry(crls[n], storeId(0), name(0), provider());
1062
QString ename = c->makeName();
1063
QString eid = QString::number(qHash(certs[n].toDER()));
1064
c->item_name = ename;
1066
c->item_save = makeId(storeId(0), name(0), eid, ename, "crl", crls[n].toPEM());
1169
c->_id = c->simpleId();
1170
c->_name = c->simpleName();
1074
1177
virtual KeyStoreEntryContext *entryPassive(const QString &serialized)
1076
QString storeId, storeName, eid, ename, etype, pem;
1077
if(parseId(serialized, &storeId, &storeName, &eid, &ename, &etype, &pem))
1081
Certificate cert = Certificate::fromPEM(pem);
1084
DefaultKeyStoreEntry *c = new DefaultKeyStoreEntry(cert, storeId, storeName, provider());
1085
c->item_name = ename;
1087
c->item_save = serialized;
1090
else if(etype == "crl")
1092
CRL crl = CRL::fromPEM(pem);
1095
DefaultKeyStoreEntry *c = new DefaultKeyStoreEntry(crl, storeId, storeName, provider());
1096
c->item_name = ename;
1098
c->item_save = serialized;
1179
return DefaultKeyStoreEntry::deserialize(serialized, provider());
1106
1183
//----------------------------------------------------------------------------
1107
1184
// DefaultProvider
1108
1185
//----------------------------------------------------------------------------
1186
static bool unescape_config_stringlist(const QString &in, QStringList *_out)
1189
QStringList list = in.split(',');
1190
for(int n = 0; n < list.count(); ++n)
1193
if(!unescape_string(list[n], &str))
1195
out += str.trimmed();
1109
1201
class DefaultProvider : public Provider
1178
1270
QString skip_plugins_str = config["skip_plugins"].toString();
1179
1271
QString plugin_priorities_str = config["plugin_priorities"].toString();
1181
QStringList skip_plugins = skip_plugins_str.split(",");
1182
for(int n = 0; n < skip_plugins.count(); ++n)
1184
QString &s = skip_plugins[n];
1185
s = unescape_string(s).trimmed();
1188
QStringList plugin_priorities = plugin_priorities_str.split(",");
1275
QStringList skip_plugins;
1276
if(unescape_config_stringlist(skip_plugins_str, &tmp))
1279
QStringList plugin_priorities;
1280
if(unescape_config_stringlist(plugin_priorities_str, &tmp))
1281
plugin_priorities = tmp;
1189
1283
for(int n = 0; n < plugin_priorities.count(); ++n)
1191
1285
QString &s = plugin_priorities[n];
1192
s = unescape_string(s).trimmed();
1194
1287
// make sure the entry ends with ":number"
1195
1288
int x = s.indexOf(':');