summaryrefslogtreecommitdiffstats
path: root/kio/kssl/ksslpkcs12.cc
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commitce4a32fe52ef09d8f5ff1dd22c001110902b60a2 (patch)
tree5ac38a06f3dde268dc7927dc155896926aaf7012 /kio/kssl/ksslpkcs12.cc
downloadtdelibs-ce4a32fe52ef09d8f5ff1dd22c001110902b60a2.tar.gz
tdelibs-ce4a32fe52ef09d8f5ff1dd22c001110902b60a2.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdelibs@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kio/kssl/ksslpkcs12.cc')
-rw-r--r--kio/kssl/ksslpkcs12.cc295
1 files changed, 295 insertions, 0 deletions
diff --git a/kio/kssl/ksslpkcs12.cc b/kio/kssl/ksslpkcs12.cc
new file mode 100644
index 000000000..d890df8eb
--- /dev/null
+++ b/kio/kssl/ksslpkcs12.cc
@@ -0,0 +1,295 @@
+/* This file is part of the KDE project
+ *
+ * Copyright (C) 2001 George Staikos <staikos@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <kopenssl.h>
+
+#include <qstring.h>
+#include <qfile.h>
+#include <ksslall.h>
+#include <kdebug.h>
+#include <ktempfile.h>
+#include <kmdcodec.h>
+
+#include <assert.h>
+
+#ifdef KSSL_HAVE_SSL
+#define sk_new kossl->sk_new
+#define sk_push kossl->sk_push
+#define sk_free kossl->sk_free
+#define sk_value kossl->sk_value
+#define sk_num kossl->sk_num
+#define sk_dup kossl->sk_dup
+#define sk_pop kossl->sk_pop
+#endif
+
+
+KSSLPKCS12::KSSLPKCS12() {
+ _pkcs = NULL;
+ _pkey = NULL;
+ _cert = NULL;
+ _caStack = NULL;
+ kossl = KOSSL::self();
+}
+
+
+
+KSSLPKCS12::~KSSLPKCS12() {
+#ifdef KSSL_HAVE_SSL
+ if (_pkey) kossl->EVP_PKEY_free(_pkey);
+ if (_caStack) {
+ for (;;) {
+ X509* x5 = sk_X509_pop(_caStack);
+ if (!x5) break;
+ kossl->X509_free(x5);
+ }
+ sk_X509_free(_caStack);
+ }
+ if (_pkcs) kossl->PKCS12_free(_pkcs);
+#endif
+ if (_cert) delete _cert;
+}
+
+
+KSSLPKCS12* KSSLPKCS12::fromString(QString base64, QString password) {
+#ifdef KSSL_HAVE_SSL
+KTempFile ktf;
+
+ if (base64.isEmpty()) return NULL;
+ QByteArray qba, qbb = QCString(base64.latin1()).copy();
+ KCodecs::base64Decode(qbb, qba);
+ ktf.file()->writeBlock(qba);
+ ktf.close();
+ KSSLPKCS12* rc = loadCertFile(ktf.name(), password);
+ ktf.unlink();
+ return rc;
+#endif
+return NULL;
+}
+
+
+
+KSSLPKCS12* KSSLPKCS12::loadCertFile(QString filename, QString password) {
+#ifdef KSSL_HAVE_SSL
+QFile qf(filename);
+PKCS12 *newpkcs = NULL;
+
+ if (!qf.open(IO_ReadOnly))
+ return NULL;
+
+ FILE *fp = fdopen(qf.handle(), "r");
+ if (!fp) return NULL;
+
+ newpkcs = KOSSL::self()->d2i_PKCS12_fp(fp, &newpkcs);
+
+ fclose(fp);
+ if (!newpkcs) {
+ KOSSL::self()->ERR_clear_error();
+ return NULL;
+ }
+
+ KSSLPKCS12 *c = new KSSLPKCS12;
+ c->setCert(newpkcs);
+
+ // Now we parse it to see if we can decrypt it and interpret it
+ if (!c->parse(password)) {
+ delete c; c = NULL;
+ }
+
+ return c;
+#endif
+return NULL;
+}
+
+
+void KSSLPKCS12::setCert(PKCS12 *c) {
+#ifdef KSSL_HAVE_SSL
+ _pkcs = c;
+#endif
+}
+
+
+bool KSSLPKCS12::changePassword(QString pold, QString pnew) {
+#ifdef KSSL_HAVE_SSL
+ // OpenSSL makes me cast away the const here. argh
+ return (0 == kossl->PKCS12_newpass(_pkcs,
+ pold.isNull() ? (char *)"" : (char *)pold.latin1(),
+ pnew.isNull() ? (char *)"" : (char *)pnew.latin1()));
+#endif
+return false;
+}
+
+
+bool KSSLPKCS12::parse(QString pass) {
+#ifdef KSSL_HAVE_SSL
+X509 *x = NULL;
+
+ assert(_pkcs); // if you're calling this before pkcs gets set, it's a BUG!
+
+ if (_cert) delete _cert;
+ if (_pkey) kossl->EVP_PKEY_free(_pkey);
+ if (_caStack) {
+ for (;;) {
+ X509* x5 = sk_X509_pop(_caStack);
+ if (!x5) break;
+ kossl->X509_free(x5);
+ }
+ sk_X509_free(_caStack);
+ }
+ _pkey = NULL;
+ _caStack = NULL;
+ _cert = NULL;
+
+ int rc = kossl->PKCS12_parse(_pkcs, pass.latin1(), &_pkey, &x, &_caStack);
+
+ if (rc == 1) {
+ // kdDebug(7029) << "PKCS12_parse success" << endl;
+ if (x) {
+ _cert = new KSSLCertificate;
+ _cert->setCert(x);
+ if (_caStack) {
+ _cert->setChain(_caStack);
+ }
+ return true;
+ }
+ } else {
+ _caStack = NULL;
+ _pkey = NULL;
+ kossl->ERR_clear_error();
+ }
+#endif
+return false;
+}
+
+
+EVP_PKEY *KSSLPKCS12::getPrivateKey() {
+ return _pkey;
+}
+
+
+KSSLCertificate *KSSLPKCS12::getCertificate() {
+ return _cert;
+}
+
+
+QString KSSLPKCS12::toString() {
+QString base64;
+#ifdef KSSL_HAVE_SSL
+unsigned char *p;
+int len;
+
+ len = kossl->i2d_PKCS12(_pkcs, NULL);
+ if (len >= 0) {
+ char *buf = new char[len];
+ p = (unsigned char *)buf;
+ kossl->i2d_PKCS12(_pkcs, &p);
+ QByteArray qba;
+ qba.setRawData(buf, len);
+ base64 = KCodecs::base64Encode(qba);
+ qba.resetRawData(buf, len);
+ delete[] buf;
+ }
+#endif
+return base64;
+}
+
+
+
+bool KSSLPKCS12::toFile(QString filename) {
+#ifdef KSSL_HAVE_SSL
+QFile out(filename);
+
+ if (!out.open(IO_WriteOnly)) return false;
+
+ int fd = out.handle();
+ FILE *fp = fdopen(fd, "w");
+
+ if (!fp) {
+ unlink(filename.latin1());
+ return false;
+ }
+
+ kossl->i2d_PKCS12_fp(fp, _pkcs);
+
+ fclose(fp);
+ return true;
+#endif
+return false;
+}
+
+
+KSSLCertificate::KSSLValidation KSSLPKCS12::validate() {
+ return validate(KSSLCertificate::SSLServer);
+}
+
+
+KSSLCertificate::KSSLValidation KSSLPKCS12::validate(KSSLCertificate::KSSLPurpose p) {
+#ifdef KSSL_HAVE_SSL
+KSSLCertificate::KSSLValidation xx = _cert->validate(p);
+ if (1 != kossl->X509_check_private_key(_cert->getCert(), _pkey)) {
+ xx = KSSLCertificate::PrivateKeyFailed;
+ }
+
+return xx;
+#else
+return KSSLCertificate::NoSSL;
+#endif
+}
+
+
+KSSLCertificate::KSSLValidation KSSLPKCS12::revalidate() {
+ return revalidate(KSSLCertificate::SSLServer);
+}
+
+
+KSSLCertificate::KSSLValidation KSSLPKCS12::revalidate(KSSLCertificate::KSSLPurpose p) {
+ return _cert->revalidate(p);
+}
+
+
+bool KSSLPKCS12::isValid() {
+return isValid(KSSLCertificate::SSLServer);
+}
+
+
+bool KSSLPKCS12::isValid(KSSLCertificate::KSSLPurpose p) {
+return (validate(p) == KSSLCertificate::Ok);
+}
+
+
+QString KSSLPKCS12::name() {
+ return _cert->getSubject();
+}
+
+
+#ifdef KSSL_HAVE_SSL
+#undef sk_new
+#undef sk_push
+#undef sk_free
+#undef sk_value
+#undef sk_num
+#undef sk_pop
+#undef sk_dup
+#endif
+