Plasma
credentials.cpp
Go to the documentation of this file.
00001 /* 00002 * Copyright © 2009 Rob Scheepmaker <r.scheepmaker@student.utwente.nl> 00003 * 00004 * This program is free software; you can redistribute it and/or modify 00005 * it under the terms of the GNU Library General Public License version 2 as 00006 * published by the Free Software Foundation 00007 * 00008 * This program is distributed in the hope that it will be useful, 00009 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 * GNU General Public License for more details 00012 * 00013 * You should have received a copy of the GNU Library General Public 00014 * License along with this program; if not, write to the 00015 * Free Software Foundation, Inc., 00016 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 */ 00018 00019 #include "credentials.h" 00020 00021 #include "authorizationmanager.h" 00022 #include "config-plasma.h" 00023 00024 #include <QObject> 00025 00026 #ifdef ENABLE_REMOTE_WIDGETS 00027 #include <QtCrypto> 00028 #endif 00029 00030 #include <kdebug.h> 00031 #include <kstandarddirs.h> 00032 00033 #define REQUIRED_FEATURES "rsa,sha1,pkey" 00034 00035 namespace Plasma { 00036 00037 class CredentialsPrivate { 00038 public: 00039 CredentialsPrivate() 00040 { 00041 } 00042 00043 CredentialsPrivate(const QString &id, const QString &name, 00044 const QString &pemKey, bool isPrivateKey) 00045 : id(id), 00046 name(name) 00047 { 00048 #ifdef ENABLE_REMOTE_WIDGETS 00049 if (!QCA::isSupported(REQUIRED_FEATURES)) { 00050 kWarning() << "QCA doesn't support " << REQUIRED_FEATURES; 00051 return; 00052 } 00053 00054 if (isPrivateKey) { 00055 privateKey = QCA::PrivateKey::fromPEM(pemKey); 00056 publicKey = privateKey.toPublicKey(); 00057 } else { 00058 publicKey = QCA::PublicKey::fromPEM(pemKey); 00059 } 00060 #endif 00061 } 00062 00063 ~CredentialsPrivate() 00064 { 00065 } 00066 00067 QString id; 00068 QString name; 00069 00070 #ifdef ENABLE_REMOTE_WIDGETS 00071 QCA::PublicKey publicKey; 00072 QCA::PrivateKey privateKey; 00073 #endif 00074 }; 00075 00076 Credentials::Credentials(const QString &id, const QString &name, 00077 const QString &key, bool isPrivateKey) 00078 : d(new CredentialsPrivate(id, name, key, isPrivateKey)) 00079 { 00080 } 00081 00082 Credentials::Credentials() 00083 : d(new CredentialsPrivate()) 00084 { 00085 } 00086 00087 Credentials::Credentials(const Credentials &other) 00088 : d(new CredentialsPrivate()) 00089 { 00090 *d = *other.d; 00091 } 00092 00093 Credentials::~Credentials() 00094 { 00095 delete d; 00096 } 00097 00098 Credentials &Credentials::operator=(const Credentials &other) 00099 { 00100 *d = *other.d; 00101 return *this; 00102 } 00103 00104 Credentials Credentials::createCredentials(const QString &name) 00105 { 00106 #ifdef ENABLE_REMOTE_WIDGETS 00107 if (!QCA::isSupported(REQUIRED_FEATURES)) { 00108 kWarning() << "QCA doesn't support " << REQUIRED_FEATURES; 00109 return Credentials(); 00110 } 00111 00112 QCA::KeyGenerator generator; 00113 QCA::PrivateKey key = generator.createRSA(2048); 00114 QString pemKey(key.toPublicKey().toPEM()); 00115 QString id = QCA::Hash("sha1").hashToString(pemKey.toAscii()); 00116 return Credentials(id, name, key.toPEM(), true); 00117 #else 00118 return Credentials(); 00119 #endif 00120 } 00121 00122 TrustLevel Credentials::trustLevel() const 00123 { 00134 //Trust no one ;) 00135 return ValidCredentials; 00136 } 00137 00138 bool Credentials::isValid() const 00139 { 00140 #ifdef ENABLE_REMOTE_WIDGETS 00141 if (!QCA::isSupported(REQUIRED_FEATURES)) { 00142 kWarning() << "QCA doesn't support " << REQUIRED_FEATURES; 00143 return false; 00144 } 00145 00146 if (d->publicKey.isNull()) { 00147 return false; 00148 } else { 00149 QString id = QCA::Hash("sha1").hashToString(d->publicKey.toPEM().toAscii()); 00150 return (id == d->id); 00151 } 00152 #else 00153 kDebug() << "libplasma is compiled without support for remote widgets. Key invalid."; 00154 return false; 00155 #endif 00156 } 00157 00158 QString Credentials::name() const 00159 { 00160 return d->name; 00161 } 00162 00163 QString Credentials::id() const 00164 { 00165 return d->id; 00166 } 00167 00168 bool Credentials::isValidSignature(const QByteArray &signature, const QByteArray &payload) 00169 { 00170 #ifdef ENABLE_REMOTE_WIDGETS 00171 if (!QCA::isSupported(REQUIRED_FEATURES)) { 00172 kWarning() << "QCA doesn't support " << REQUIRED_FEATURES; 00173 return false; 00174 } 00175 00176 if (d->publicKey.canVerify()) { 00177 if (!isValid()) { 00178 kDebug() << "Key is null?"; 00179 } 00180 QCA::PublicKey publicKey = QCA::PublicKey::fromPEM(d->publicKey.toPEM()); 00181 publicKey.startVerify( QCA::EMSA3_MD5 ); 00182 publicKey.update(payload); 00183 return ( publicKey.validSignature( signature ) ); 00184 } else { 00185 kDebug() << "Can't verify?"; 00186 return false; 00187 } 00188 #else 00189 return false; 00190 #endif 00191 } 00192 00193 bool Credentials::canSign() const 00194 { 00195 #ifdef ENABLE_REMOTE_WIDGETS 00196 if (!QCA::isSupported(REQUIRED_FEATURES)) { 00197 kWarning() << "QCA doesn't support " << REQUIRED_FEATURES; 00198 return false; 00199 } 00200 00201 return d->privateKey.canSign(); 00202 #else 00203 return false; 00204 #endif 00205 } 00206 00207 QByteArray Credentials::signMessage(const QByteArray &message) 00208 { 00209 #ifdef ENABLE_REMOTE_WIDGETS 00210 if(!QCA::isSupported(REQUIRED_FEATURES)) { 00211 kDebug() << "RSA not supported"; 00212 return QByteArray(); 00213 } else if (canSign()) { 00214 //QCA::PrivateKey privateKey = QCA::PrivateKey::fromPEM(d->privateKey.toPEM()); 00215 d->privateKey.startSign( QCA::EMSA3_MD5 ); 00216 d->privateKey.update( message ); 00217 QByteArray signature = d->privateKey.signature(); 00218 return signature; 00219 } else { 00220 return QByteArray(); 00221 } 00222 #else 00223 return QByteArray(); 00224 #endif 00225 } 00226 00227 Credentials Credentials::toPublicCredentials() const 00228 { 00229 #ifdef ENABLE_REMOTE_WIDGETS 00230 Credentials result(*this); 00231 result.d->privateKey = QCA::PrivateKey(); 00232 return result; 00233 #else 00234 return Credentials(); 00235 #endif 00236 } 00237 00238 QDataStream &operator<<(QDataStream &out, const Credentials &myObj) 00239 { 00240 #ifdef ENABLE_REMOTE_WIDGETS 00241 if (!QCA::isSupported(REQUIRED_FEATURES)) { 00242 kWarning() << "QCA doesn't support " << REQUIRED_FEATURES; 00243 return out; 00244 } 00245 00246 QString privateKeyPem; 00247 QString publicKeyPem; 00248 00249 if (!myObj.d->privateKey.isNull()) { 00250 privateKeyPem = myObj.d->privateKey.toPEM(); 00251 } 00252 if (!myObj.d->publicKey.isNull()) { 00253 publicKeyPem = myObj.d->publicKey.toPEM(); 00254 } 00255 00256 out << 1 << myObj.d->id << myObj.d->name << privateKeyPem << publicKeyPem; 00257 #endif 00258 00259 return out; 00260 } 00261 00262 QDataStream &operator>>(QDataStream &in, Credentials &myObj) 00263 { 00264 #ifdef ENABLE_REMOTE_WIDGETS 00265 if (!QCA::isSupported(REQUIRED_FEATURES)) { 00266 kWarning() << "QCA doesn't support " << REQUIRED_FEATURES; 00267 return in; 00268 } 00269 00270 QString privateKeyString; 00271 QString publicKeyString; 00272 uint version; 00273 00274 in >> version >> myObj.d->id >> myObj.d->name >> privateKeyString >> publicKeyString; 00275 QCA::ConvertResult conversionResult; 00276 00277 if (!privateKeyString.isEmpty()) { 00278 myObj.d->privateKey = QCA::PrivateKey::fromPEM(privateKeyString, 00279 QByteArray(), &conversionResult); 00280 } 00281 00282 if (!publicKeyString.isEmpty()) { 00283 myObj.d->publicKey = QCA::PublicKey::fromPEM(publicKeyString, &conversionResult); 00284 } 00285 00286 if (conversionResult != QCA::ConvertGood) { 00287 kDebug() << "Unsuccessfull conversion of key?"; 00288 } 00289 #endif 00290 00291 return in; 00292 } 00293 00294 }
KDE 4.6 API Reference