KIO
ksslpkcs12.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <config.h>
00023 #include <ksslconfig.h>
00024
00025 #include <kopenssl.h>
00026
00027 #include <QtCore/QString>
00028 #include <QtCore/QFile>
00029
00030 #include <ksslall.h>
00031 #include <kdebug.h>
00032 #include <ktemporaryfile.h>
00033 #include <kcodecs.h>
00034
00035 #include <assert.h>
00036
00037 #ifdef KSSL_HAVE_SSL
00038 #define sk_new kossl->sk_new
00039 #define sk_push kossl->sk_push
00040 #define sk_free kossl->sk_free
00041 #define sk_value kossl->sk_value
00042 #define sk_num kossl->sk_num
00043 #define sk_dup kossl->sk_dup
00044 #define sk_pop kossl->sk_pop
00045 #endif
00046
00047
00048 KSSLPKCS12::KSSLPKCS12() {
00049 _pkcs = NULL;
00050 _pkey = NULL;
00051 _cert = NULL;
00052 _caStack = NULL;
00053 kossl = KOSSL::self();
00054 }
00055
00056
00057
00058 KSSLPKCS12::~KSSLPKCS12() {
00059 #ifdef KSSL_HAVE_SSL
00060 if (_pkey) kossl->EVP_PKEY_free(_pkey);
00061 if (_caStack) {
00062 for (;;) {
00063 X509* x5 = sk_X509_pop(_caStack);
00064 if (!x5) break;
00065 kossl->X509_free(x5);
00066 }
00067 sk_X509_free(_caStack);
00068 }
00069 if (_pkcs) kossl->PKCS12_free(_pkcs);
00070 #endif
00071 if (_cert) delete _cert;
00072 }
00073
00074
00075 KSSLPKCS12* KSSLPKCS12::fromString(const QString &base64, const QString &password) {
00076 #ifdef KSSL_HAVE_SSL
00077 KTemporaryFile ktf;
00078 ktf.open();
00079
00080 if (base64.isEmpty()) return NULL;
00081 QByteArray qba = QByteArray::fromBase64(base64.toLatin1());
00082 ktf.write(qba);
00083 ktf.flush();
00084 KSSLPKCS12* rc = loadCertFile(ktf.fileName(), password);
00085 return rc;
00086 #endif
00087 return NULL;
00088 }
00089
00090
00091
00092 KSSLPKCS12* KSSLPKCS12::loadCertFile(const QString &filename, const QString &password) {
00093 #ifdef KSSL_HAVE_SSL
00094 QFile qf(filename);
00095 PKCS12 *newpkcs = NULL;
00096
00097 if (!qf.open(QIODevice::ReadOnly))
00098 return NULL;
00099
00100 FILE *fp = fdopen(qf.handle(), "r");
00101 if (!fp) return NULL;
00102
00103 newpkcs = KOSSL::self()->d2i_PKCS12_fp(fp, &newpkcs);
00104
00105 fclose(fp);
00106 if (!newpkcs) {
00107 KOSSL::self()->ERR_clear_error();
00108 return NULL;
00109 }
00110
00111 KSSLPKCS12 *c = new KSSLPKCS12;
00112 c->setCert(newpkcs);
00113
00114
00115 if (!c->parse(password)) {
00116 delete c; c = NULL;
00117 }
00118
00119 return c;
00120 #endif
00121 return NULL;
00122 }
00123
00124
00125 void KSSLPKCS12::setCert(PKCS12 *c) {
00126 #ifdef KSSL_HAVE_SSL
00127 _pkcs = c;
00128 #endif
00129 }
00130
00131
00132 bool KSSLPKCS12::changePassword(const QString &pold, const QString &pnew) {
00133 #ifdef KSSL_HAVE_SSL
00134
00135 return (0 == kossl->PKCS12_newpass(_pkcs,
00136 pold.isNull() ? (char *)"" : (char *)pold.toLatin1().constData(),
00137 pnew.isNull() ? (char *)"" : (char *)pnew.toLatin1().constData()));
00138 #endif
00139 return false;
00140 }
00141
00142
00143 bool KSSLPKCS12::parse(const QString &pass) {
00144 #ifdef KSSL_HAVE_SSL
00145 X509 *x = NULL;
00146
00147 assert(_pkcs);
00148
00149 if (_cert) delete _cert;
00150 if (_pkey) kossl->EVP_PKEY_free(_pkey);
00151 if (_caStack) {
00152 for (;;) {
00153 X509* x5 = sk_X509_pop(_caStack);
00154 if (!x5) break;
00155 kossl->X509_free(x5);
00156 }
00157 sk_X509_free(_caStack);
00158 }
00159 _pkey = NULL;
00160 _caStack = NULL;
00161 _cert = NULL;
00162
00163 int rc = kossl->PKCS12_parse(_pkcs, pass.toLatin1(), &_pkey, &x, &_caStack);
00164
00165 if (rc == 1) {
00166
00167 if (x) {
00168 _cert = new KSSLCertificate;
00169 _cert->setCert(x);
00170 if (_caStack) {
00171 _cert->setChain(_caStack);
00172 }
00173 return true;
00174 }
00175 } else {
00176 _caStack = NULL;
00177 _pkey = NULL;
00178 kossl->ERR_clear_error();
00179 }
00180 #endif
00181 return false;
00182 }
00183
00184
00185 EVP_PKEY *KSSLPKCS12::getPrivateKey() {
00186 return _pkey;
00187 }
00188
00189
00190 KSSLCertificate *KSSLPKCS12::getCertificate() {
00191 return _cert;
00192 }
00193
00194
00195 QString KSSLPKCS12::toString()
00196 {
00197 QString base64;
00198 #ifdef KSSL_HAVE_SSL
00199 unsigned char *p;
00200 int len;
00201
00202 len = kossl->i2d_PKCS12(_pkcs, NULL);
00203 if (len > 0) {
00204 char *buf = new char[len];
00205 p = (unsigned char *)buf;
00206 kossl->i2d_PKCS12(_pkcs, &p);
00207 base64 = QByteArray::fromRawData(buf, len).toBase64();
00208 delete[] buf;
00209 }
00210 #endif
00211 return base64;
00212 }
00213
00214
00215
00216 bool KSSLPKCS12::toFile(const QString &filename) {
00217 #ifdef KSSL_HAVE_SSL
00218 QFile out(filename);
00219
00220 if (!out.open(QIODevice::WriteOnly)) return false;
00221
00222 int fd = out.handle();
00223 FILE *fp = fdopen(fd, "w");
00224
00225 if (!fp) {
00226 unlink(filename.toLatin1());
00227 return false;
00228 }
00229
00230 kossl->i2d_PKCS12_fp(fp, _pkcs);
00231
00232 fclose(fp);
00233 return true;
00234 #endif
00235 return false;
00236 }
00237
00238
00239 KSSLCertificate::KSSLValidation KSSLPKCS12::validate() {
00240 return validate(KSSLCertificate::SSLServer);
00241 }
00242
00243
00244 KSSLCertificate::KSSLValidation KSSLPKCS12::validate(KSSLCertificate::KSSLPurpose p) {
00245 #ifdef KSSL_HAVE_SSL
00246 KSSLCertificate::KSSLValidation xx = _cert->validate(p);
00247 if (1 != kossl->X509_check_private_key(_cert->getCert(), _pkey)) {
00248 xx = KSSLCertificate::PrivateKeyFailed;
00249 }
00250
00251 return xx;
00252 #else
00253 return KSSLCertificate::NoSSL;
00254 #endif
00255 }
00256
00257
00258 KSSLCertificate::KSSLValidation KSSLPKCS12::revalidate() {
00259 return revalidate(KSSLCertificate::SSLServer);
00260 }
00261
00262
00263 KSSLCertificate::KSSLValidation KSSLPKCS12::revalidate(KSSLCertificate::KSSLPurpose p) {
00264 return _cert->revalidate(p);
00265 }
00266
00267
00268 bool KSSLPKCS12::isValid() {
00269 return isValid(KSSLCertificate::SSLServer);
00270 }
00271
00272
00273 bool KSSLPKCS12::isValid(KSSLCertificate::KSSLPurpose p) {
00274 return (validate(p) == KSSLCertificate::Ok);
00275 }
00276
00277
00278 QString KSSLPKCS12::name() const {
00279 return _cert->getSubject();
00280 }
00281
00282
00283 #ifdef KSSL_HAVE_SSL
00284 #undef sk_new
00285 #undef sk_push
00286 #undef sk_free
00287 #undef sk_value
00288 #undef sk_num
00289 #undef sk_pop
00290 #undef sk_dup
00291 #endif
00292