• Skip to content
  • Skip to link menu
KDE 4.1 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

KIO

ksslcertificate.cpp

Go to the documentation of this file.
00001 /* This file is part of the KDE project
00002  *
00003  * Copyright (C) 2000-2003 George Staikos <staikos@kde.org>
00004  *               2008 Richard Hartmann <richih-kde@net.in.tum.de>
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Library General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Library General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Library General Public License
00017  * along with this library; see the file COPYING.LIB.  If not, write to
00018  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019  * Boston, MA 02110-1301, USA.
00020  */
00021 
00022 #include "ksslcertificate.h"
00023 
00024 #include <config.h>
00025 #include <ksslconfig.h>
00026 
00027 
00028 
00029 #include <unistd.h>
00030 #include <QtCore/QString>
00031 #include <QtCore/QStringList>
00032 #include <QtCore/QFile>
00033 
00034 #include "kssldefs.h"
00035 #include "ksslcertchain.h"
00036 #include "ksslutils.h"
00037 
00038 #include <kstandarddirs.h>
00039 #include <kcodecs.h>
00040 #include <kde_file.h>
00041 #include <klocale.h>
00042 #include <QtCore/QDate>
00043 #include <ktemporaryfile.h>
00044 
00045 #include <sys/types.h>
00046 
00047 #ifdef HAVE_SYS_STAT_H
00048 #include <sys/stat.h>
00049 #endif
00050 
00051 // this hack provided by Malte Starostik to avoid glibc/openssl bug
00052 // on some systems
00053 #ifdef KSSL_HAVE_SSL
00054 #define crypt _openssl_crypt
00055 #include <openssl/ssl.h>
00056 #include <openssl/x509.h>
00057 #include <openssl/x509v3.h>
00058 #include <openssl/x509_vfy.h>
00059 #include <openssl/pem.h>
00060 #undef crypt
00061 #endif
00062 
00063 #include <kopenssl.h>
00064 #include <kdebug.h>
00065 #include "ksslx509v3.h"
00066 
00067 
00068 
00069 static char hv[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
00070 
00071 
00072 class KSSLCertificatePrivate {
00073 public:
00074     KSSLCertificatePrivate() {
00075         kossl = KOSSL::self();
00076         _lastPurpose = KSSLCertificate::None;
00077     }
00078 
00079     ~KSSLCertificatePrivate() {
00080     }
00081 
00082     KSSLCertificate::KSSLValidation m_stateCache;
00083     bool m_stateCached;
00084     #ifdef KSSL_HAVE_SSL
00085         X509 *m_cert;
00086     #endif
00087     KOSSL *kossl;
00088     KSSLCertChain _chain;
00089     KSSLX509V3 _extensions;
00090     KSSLCertificate::KSSLPurpose _lastPurpose;
00091 };
00092 
00093 KSSLCertificate::KSSLCertificate() {
00094     d = new KSSLCertificatePrivate;
00095     d->m_stateCached = false;
00096     KGlobal::dirs()->addResourceType("kssl", "data", "kssl");
00097     #ifdef KSSL_HAVE_SSL
00098         d->m_cert = NULL;
00099     #endif
00100 }
00101 
00102 
00103 KSSLCertificate::KSSLCertificate(const KSSLCertificate& x) {
00104     d = new KSSLCertificatePrivate;
00105     d->m_stateCached = false;
00106     KGlobal::dirs()->addResourceType("kssl", "data", "kssl");
00107     #ifdef KSSL_HAVE_SSL
00108         d->m_cert = NULL;
00109         setCert(KOSSL::self()->X509_dup(const_cast<KSSLCertificate&>(x).getCert()));
00110         KSSLCertChain *c = x.d->_chain.replicate();
00111         setChain(c->rawChain());
00112         delete c;
00113     #endif
00114 }
00115 
00116 
00117 
00118 KSSLCertificate::~KSSLCertificate() {
00119 #ifdef KSSL_HAVE_SSL
00120     if (d->m_cert) {
00121         d->kossl->X509_free(d->m_cert);
00122     }
00123 #endif
00124     delete d;
00125 }
00126 
00127 
00128 KSSLCertChain& KSSLCertificate::chain() {
00129     return d->_chain;
00130 }
00131 
00132 
00133 KSSLCertificate *KSSLCertificate::fromX509(X509 *x5) {
00134     KSSLCertificate *n = NULL;
00135 #ifdef KSSL_HAVE_SSL
00136     if (x5) {
00137         n = new KSSLCertificate;
00138         n->setCert(KOSSL::self()->X509_dup(x5));
00139     }
00140 #endif
00141     return n;
00142 }
00143 
00144 
00145 KSSLCertificate *KSSLCertificate::fromString(const QByteArray &cert) {
00146     KSSLCertificate *n = NULL;
00147 #ifdef KSSL_HAVE_SSL
00148     if (cert.isEmpty()) {
00149         return NULL;
00150     }
00151 
00152     QByteArray qba = QByteArray::fromBase64(cert);
00153     unsigned char *qbap = reinterpret_cast<unsigned char *>(qba.data());
00154     X509 *x5c = KOSSL::self()->d2i_X509(NULL, &qbap, qba.size());
00155     if (!x5c) {
00156         return NULL;
00157     }
00158 
00159     n = new KSSLCertificate;
00160     n->setCert(x5c);
00161 #endif
00162     return n;
00163 }
00164 
00165 
00166 
00167 QString KSSLCertificate::getSubject() const {
00168     QString rc = "";
00169 
00170 #ifdef KSSL_HAVE_SSL
00171     char *t = d->kossl->X509_NAME_oneline(d->kossl->X509_get_subject_name(d->m_cert), 0, 0);
00172     if (!t) {
00173         return rc;
00174     }
00175     rc = t;
00176     d->kossl->OPENSSL_free(t);
00177 #endif
00178     return rc;
00179 }
00180 
00181 
00182 QString KSSLCertificate::getSerialNumber() const {
00183     QString rc = "";
00184 
00185 #ifdef KSSL_HAVE_SSL
00186     ASN1_INTEGER *aint = d->kossl->X509_get_serialNumber(d->m_cert);
00187     if (aint) {
00188         rc = ASN1_INTEGER_QString(aint);
00189         // d->kossl->ASN1_INTEGER_free(aint);   this makes the sig test fail
00190     }
00191 #endif
00192     return rc;
00193 }
00194 
00195 
00196 QString KSSLCertificate::getSignatureText() const {
00197     QString rc = "";
00198 
00199 #ifdef KSSL_HAVE_SSL
00200     char *s;
00201     int n, i;
00202 
00203     i = d->kossl->OBJ_obj2nid(d->m_cert->sig_alg->algorithm);
00204     rc = i18n("Signature Algorithm: ");
00205     rc += (i == NID_undef)?i18n("Unknown"):QString(d->kossl->OBJ_nid2ln(i));
00206 
00207     rc += '\n';
00208     rc += i18n("Signature Contents:");
00209     n = d->m_cert->signature->length;
00210     s = (char *)d->m_cert->signature->data;
00211     for (i = 0; i < n; i++) {
00212         if (i%20 != 0) {
00213             rc += ':';
00214         }
00215         else {
00216             rc += '\n';
00217         }
00218         rc.append(QChar(hv[(s[i]&0xf0)>>4]));
00219         rc.append(QChar(hv[s[i]&0x0f]));
00220     }
00221 
00222 #endif
00223 
00224     return rc;
00225 }
00226 
00227 
00228 void KSSLCertificate::getEmails(QStringList &to) const {
00229     to.clear();
00230 #ifdef KSSL_HAVE_SSL
00231     if (!d->m_cert) {
00232         return;
00233     }
00234 
00235     STACK *s = d->kossl->X509_get1_email(d->m_cert);
00236     if (s) {
00237         for(int n=0; n < s->num; n++) {
00238             to.append(d->kossl->sk_value(s,n));
00239         }
00240         d->kossl->X509_email_free(s);
00241     }
00242 #endif
00243 }
00244 
00245 
00246 QString KSSLCertificate::getKDEKey() const {
00247     return getSubject() + " (" + getMD5DigestText() + ')';
00248 }
00249 
00250 
00251 QString KSSLCertificate::getMD5DigestFromKDEKey(const QString &k) {
00252     QString rc;
00253     int pos = k.lastIndexOf('(');
00254     if (pos != -1) {
00255         unsigned int len = k.length();
00256         if (k.at(len-1) == ')') {
00257             rc = k.mid(pos+1, len-pos-2);
00258         }
00259     }
00260     return rc;
00261 }
00262 
00263 
00264 QString KSSLCertificate::getMD5DigestText() const {
00265 QString rc = "";
00266 
00267 #ifdef KSSL_HAVE_SSL
00268     unsigned int n;
00269     unsigned char md[EVP_MAX_MD_SIZE];
00270 
00271     if (!d->kossl->X509_digest(d->m_cert, d->kossl->EVP_md5(), md, &n)) {
00272         return rc;
00273     }
00274 
00275     for (unsigned int j = 0; j < n; j++) {
00276         if (j > 0) {
00277             rc += ':';
00278         }
00279         rc.append(QChar(hv[(md[j]&0xf0)>>4]));
00280         rc.append(QChar(hv[md[j]&0x0f]));
00281     }
00282 
00283 #endif
00284 
00285     return rc;
00286 }
00287 
00288 
00289 
00290 QString KSSLCertificate::getMD5Digest() const {
00291 QString rc = "";
00292 
00293 #ifdef KSSL_HAVE_SSL
00294     unsigned int n;
00295     unsigned char md[EVP_MAX_MD_SIZE];
00296 
00297     if (!d->kossl->X509_digest(d->m_cert, d->kossl->EVP_md5(), md, &n)) {
00298         return rc;
00299     }
00300 
00301     for (unsigned int j = 0; j < n; j++) {
00302         rc.append(QLatin1Char(hv[(md[j]&0xf0)>>4]));
00303         rc.append(QLatin1Char(hv[md[j]&0x0f]));
00304     }
00305 
00306 #endif
00307 
00308     return rc;
00309 }
00310 
00311 
00312 
00313 QString KSSLCertificate::getKeyType() const {
00314 QString rc = "";
00315 
00316 #ifdef KSSL_HAVE_SSL
00317     EVP_PKEY *pkey = d->kossl->X509_get_pubkey(d->m_cert);
00318     if (pkey) {
00319         #ifndef NO_RSA
00320             if (pkey->type == EVP_PKEY_RSA) {
00321                 rc = "RSA";
00322             }
00323             else
00324         #endif
00325         #ifndef NO_DSA
00326             if (pkey->type == EVP_PKEY_DSA) {
00327                 rc = "DSA";
00328             }
00329             else
00330         #endif
00331                 rc = "Unknown";
00332         d->kossl->EVP_PKEY_free(pkey);
00333     }
00334 #endif
00335 
00336     return rc;
00337 }
00338 
00339 
00340 
00341 QString KSSLCertificate::getPublicKeyText() const {
00342 QString rc = "";
00343 char *x = NULL;
00344 
00345 #ifdef KSSL_HAVE_SSL
00346     EVP_PKEY *pkey = d->kossl->X509_get_pubkey(d->m_cert);
00347     if (pkey) {
00348         rc = i18nc("Unknown", "Unknown key algorithm");
00349         #ifndef NO_RSA
00350             if (pkey->type == EVP_PKEY_RSA) {
00351                 x = d->kossl->BN_bn2hex(pkey->pkey.rsa->n);
00352                 rc = i18n("Key type: RSA (%1 bit)", strlen(x)*4) + '\n';
00353 
00354                 rc += i18n("Modulus: ");
00355                 for (unsigned int i = 0; i < strlen(x); i++) {
00356                     if (i%40 != 0 && i%2 == 0) {
00357                         rc += ':';
00358                     }
00359                     else if (i%40 == 0) {
00360                         rc += '\n';
00361                     }
00362                     rc += x[i];
00363                 }
00364                 rc += '\n';
00365                 d->kossl->OPENSSL_free(x);
00366 
00367                 x = d->kossl->BN_bn2hex(pkey->pkey.rsa->e);
00368                 rc += i18n("Exponent: 0x") + QLatin1String(x) +
00369                   QLatin1String("\n");
00370                 d->kossl->OPENSSL_free(x);
00371             }
00372         #endif
00373         #ifndef NO_DSA
00374             if (pkey->type == EVP_PKEY_DSA) {
00375                 x = d->kossl->BN_bn2hex(pkey->pkey.dsa->p);
00376                 // hack - this may not be always accurate
00377                 rc = i18n("Key type: DSA (%1 bit)", strlen(x)*4) + '\n';
00378 
00379                 rc += i18n("Prime: ");
00380                 for (unsigned int i = 0; i < strlen(x); i++) {
00381                     if (i%40 != 0 && i%2 == 0) {
00382                         rc += ':';
00383                     }
00384                     else if (i%40 == 0) {
00385                         rc += '\n';
00386                     }
00387                     rc += x[i];
00388                 }
00389                 rc += '\n';
00390                 d->kossl->OPENSSL_free(x);
00391 
00392                 x = d->kossl->BN_bn2hex(pkey->pkey.dsa->q);
00393                 rc += i18n("160 bit prime factor: ");
00394                 for (unsigned int i = 0; i < strlen(x); i++) {
00395                     if (i%40 != 0 && i%2 == 0) {
00396                         rc += ':';
00397                     }
00398                     else if (i%40 == 0) {
00399                         rc += '\n';
00400                     }
00401                     rc += x[i];
00402                 }
00403                 rc += '\n';
00404                 d->kossl->OPENSSL_free(x);
00405 
00406                 x = d->kossl->BN_bn2hex(pkey->pkey.dsa->g);
00407                 rc += QString("g: ");
00408                 for (unsigned int i = 0; i < strlen(x); i++) {
00409                     if (i%40 != 0 && i%2 == 0) {
00410                         rc += ':';
00411                     }
00412                     else if (i%40 == 0) {
00413                         rc += '\n';
00414                     }
00415                     rc += x[i];
00416                 }
00417                 rc += '\n';
00418                 d->kossl->OPENSSL_free(x);
00419 
00420                 x = d->kossl->BN_bn2hex(pkey->pkey.dsa->pub_key);
00421                 rc += i18n("Public key: ");
00422                 for (unsigned int i = 0; i < strlen(x); i++) {
00423                     if (i%40 != 0 && i%2 == 0) {
00424                         rc += ':';
00425                     }
00426                     else if (i%40 == 0) {
00427                         rc += '\n';
00428                     }
00429                     rc += x[i];
00430                 }
00431                 rc += '\n';
00432                 d->kossl->OPENSSL_free(x);
00433             }
00434         #endif
00435         d->kossl->EVP_PKEY_free(pkey);
00436     }
00437 #endif
00438 
00439     return rc;
00440 }
00441 
00442 
00443 
00444 QString KSSLCertificate::getIssuer() const {
00445 QString rc = "";
00446 
00447 #ifdef KSSL_HAVE_SSL
00448     char *t = d->kossl->X509_NAME_oneline(d->kossl->X509_get_issuer_name(d->m_cert), 0, 0);
00449 
00450     if (!t) {
00451         return rc;
00452     }
00453 
00454     rc = t;
00455     d->kossl->OPENSSL_free(t);
00456 #endif
00457 
00458     return rc;
00459 }
00460 
00461 void KSSLCertificate::setChain(void *c) {
00462 #ifdef KSSL_HAVE_SSL
00463     d->_chain.setChain(c);
00464 #endif
00465     d->m_stateCached = false;
00466     d->m_stateCache = KSSLCertificate::Unknown;
00467 }
00468 
00469 void KSSLCertificate::setCert(X509 *c) {
00470 #ifdef KSSL_HAVE_SSL
00471     d->m_cert = c;
00472     if (c) {
00473         d->_extensions.flags = 0;
00474         d->kossl->X509_check_purpose(c, -1, 0);    // setup the fields (!!)
00475 
00476 #if 0
00477         kDebug(7029) << "---------------- Certificate ------------------"
00478                   << endl;
00479         kDebug(7029) << getSubject();
00480 #endif
00481 
00482         for (int j = 0; j < d->kossl->X509_PURPOSE_get_count(); j++) {
00483             X509_PURPOSE *ptmp = d->kossl->X509_PURPOSE_get0(j);
00484             int id = d->kossl->X509_PURPOSE_get_id(ptmp);
00485             for (int ca = 0; ca < 2; ca++) {
00486                 int idret = d->kossl->X509_check_purpose(c, id, ca);
00487                 if (idret == 1 || idret == 2) {   // have it
00488                     // kDebug() << "PURPOSE: " << id << (ca?" CA":"");
00489                     if (!ca) {
00490                         d->_extensions.flags |= (1L <<(id-1));
00491                     }
00492                     else d->_extensions.flags |= (1L <<(16+id-1));
00493                 } else {
00494                     if (!ca) {
00495                         d->_extensions.flags &= ~(1L <<(id-1));
00496                     }
00497                     else d->_extensions.flags &= ~(1L <<(16+id-1));
00498                 }
00499             }
00500         }
00501 
00502 #if 0
00503         kDebug(7029) << "flags: " << QString::number(c->ex_flags, 2)
00504                   << "\nkeyusage: " << QString::number(c->ex_kusage, 2)
00505                   << "\nxkeyusage: " << QString::number(c->ex_xkusage, 2)
00506                   << "\nnscert: " << QString::number(c->ex_nscert, 2)
00507                   << endl;
00508         if (c->ex_flags & EXFLAG_KUSAGE)
00509             kDebug(7029) << "     --- Key Usage extensions found";
00510         else kDebug(7029) << "     --- Key Usage extensions NOT found";
00511 
00512         if (c->ex_flags & EXFLAG_XKUSAGE)
00513             kDebug(7029) << "     --- Extended key usage extensions found";
00514         else kDebug(7029) << "     --- Extended key usage extensions NOT found";
00515 
00516         if (c->ex_flags & EXFLAG_NSCERT)
00517             kDebug(7029) << "     --- NS extensions found";
00518         else kDebug(7029) << "     --- NS extensions NOT found";
00519 
00520         if (d->_extensions.certTypeSSLCA())
00521             kDebug(7029) << "NOTE: this is an SSL CA file.";
00522         else kDebug(7029) << "NOTE: this is NOT an SSL CA file.";
00523 
00524         if (d->_extensions.certTypeEmailCA())
00525             kDebug(7029) << "NOTE: this is an EMAIL CA file.";
00526         else kDebug(7029) << "NOTE: this is NOT an EMAIL CA file.";
00527 
00528         if (d->_extensions.certTypeCodeCA())
00529             kDebug(7029) << "NOTE: this is a CODE CA file.";
00530         else kDebug(7029) << "NOTE: this is NOT a CODE CA file.";
00531 
00532         if (d->_extensions.certTypeSSLClient())
00533             kDebug(7029) << "NOTE: this is an SSL client.";
00534         else kDebug(7029) << "NOTE: this is NOT an SSL client.";
00535 
00536         if (d->_extensions.certTypeSSLServer())
00537             kDebug(7029) << "NOTE: this is an SSL server.";
00538         else kDebug(7029) << "NOTE: this is NOT an SSL server.";
00539 
00540         if (d->_extensions.certTypeNSSSLServer())
00541             kDebug(7029) << "NOTE: this is a NETSCAPE SSL server.";
00542         else kDebug(7029) << "NOTE: this is NOT a NETSCAPE SSL server.";
00543 
00544         if (d->_extensions.certTypeSMIME())
00545             kDebug(7029) << "NOTE: this is an SMIME certificate.";
00546         else kDebug(7029) << "NOTE: this is NOT an SMIME certificate.";
00547 
00548         if (d->_extensions.certTypeSMIMEEncrypt())
00549             kDebug(7029) << "NOTE: this is an SMIME encrypt cert.";
00550         else kDebug(7029) << "NOTE: this is NOT an SMIME encrypt cert.";
00551 
00552         if (d->_extensions.certTypeSMIMESign())
00553             kDebug(7029) << "NOTE: this is an SMIME sign cert.";
00554         else kDebug(7029) << "NOTE: this is NOT an SMIME sign cert.";
00555 
00556         if (d->_extensions.certTypeCRLSign())
00557             kDebug(7029) << "NOTE: this is a CRL signer.";
00558         else kDebug(7029) << "NOTE: this is NOT a CRL signer.";
00559 
00560         kDebug(7029) << "-----------------------------------------------"
00561                  << endl;
00562 #endif
00563     }
00564 #endif
00565     d->m_stateCached = false;
00566     d->m_stateCache = KSSLCertificate::Unknown;
00567 }
00568 
00569 X509 *KSSLCertificate::getCert() {
00570 #ifdef KSSL_HAVE_SSL
00571     return d->m_cert;
00572 #endif
00573     return 0;
00574 }
00575 
00576 // pull in the callback.  It's common across multiple files but we want
00577 // it to be hidden.
00578 
00579 #include "ksslcallback.c"
00580 
00581 
00582 bool KSSLCertificate::isValid(KSSLCertificate::KSSLPurpose p) {
00583     return (validate(p) == KSSLCertificate::Ok);
00584 }
00585 
00586 
00587 bool KSSLCertificate::isValid() {
00588     return isValid(KSSLCertificate::SSLServer);
00589 }
00590 
00591 
00592 int KSSLCertificate::purposeToOpenSSL(KSSLCertificate::KSSLPurpose p) const {
00593     int rc = 0;
00594 #ifdef KSSL_HAVE_SSL
00595     if (p == KSSLCertificate::SSLServer) {
00596         rc = X509_PURPOSE_SSL_SERVER;
00597     } else if (p == KSSLCertificate::SSLClient) {
00598         rc = X509_PURPOSE_SSL_CLIENT;
00599     } else if (p == KSSLCertificate::SMIMEEncrypt) {
00600         rc = X509_PURPOSE_SMIME_ENCRYPT;
00601     } else if (p == KSSLCertificate::SMIMESign) {
00602         rc = X509_PURPOSE_SMIME_SIGN;
00603     } else if (p == KSSLCertificate::Any) {
00604         rc = X509_PURPOSE_ANY;
00605     }
00606 #endif
00607     return rc;
00608 }
00609 
00610 
00611 // For backward compatibility
00612 KSSLCertificate::KSSLValidation KSSLCertificate::validate() {
00613     return validate(KSSLCertificate::SSLServer);
00614 }
00615 
00616 KSSLCertificate::KSSLValidation KSSLCertificate::validate(KSSLCertificate::KSSLPurpose purpose)
00617 {
00618     KSSLValidationList result = validateVerbose(purpose);
00619     if (result.isEmpty()) {
00620         return KSSLCertificate::Ok;
00621     }
00622     else
00623         return result.first();
00624 }
00625 
00626 //
00627 // See apps/verify.c in OpenSSL for the source of most of this logic.
00628 //
00629 
00630 // CRL files?  we don't do that yet
00631 KSSLCertificate::KSSLValidationList KSSLCertificate::validateVerbose(KSSLCertificate::KSSLPurpose purpose)
00632 {
00633     return validateVerbose(purpose, 0);
00634 }
00635 
00636 KSSLCertificate::KSSLValidationList KSSLCertificate::validateVerbose(KSSLCertificate::KSSLPurpose purpose, KSSLCertificate *ca)
00637 {
00638     KSSLValidationList errors;
00639     if (ca || (d->_lastPurpose != purpose)) {
00640         d->m_stateCached = false;
00641     }
00642 
00643     if (!d->m_stateCached) {
00644         d->_lastPurpose = purpose;
00645     }
00646 
00647 #ifdef KSSL_HAVE_SSL
00648     X509_STORE *certStore;
00649     X509_LOOKUP *certLookup;
00650     X509_STORE_CTX *certStoreCTX;
00651     int rc = 0;
00652 
00653     if (!d->m_cert) {
00654         errors << KSSLCertificate::Unknown;
00655         return errors;
00656     }
00657 
00658     if (d->m_stateCached) {
00659         errors << d->m_stateCache;
00660         return errors;
00661     }
00662 
00663     const QStringList qsl = KGlobal::dirs()->resourceDirs("kssl");
00664 
00665     if (qsl.isEmpty()) {
00666         errors << KSSLCertificate::NoCARoot;
00667         return errors;
00668     }
00669 
00670     KSSLCertificate::KSSLValidation ksslv = Unknown;
00671 
00672     for (QStringList::ConstIterator j = qsl.begin(); j != qsl.end(); ++j) {
00673         KDE_struct_stat sb;
00674         QString _j = (*j) + "ca-bundle.crt";
00675         if (-1 == KDE_stat(_j.toAscii().constData(), &sb)) {
00676             continue;
00677         }
00678 
00679         certStore = d->kossl->X509_STORE_new();
00680         if (!certStore) {
00681             errors << KSSLCertificate::Unknown;
00682             return errors;
00683         }
00684 
00685         X509_STORE_set_verify_cb_func(certStore, X509Callback);
00686 
00687         certLookup = d->kossl->X509_STORE_add_lookup(certStore, d->kossl->X509_LOOKUP_file());
00688         if (!certLookup) {
00689             ksslv = KSSLCertificate::Unknown;
00690             d->kossl->X509_STORE_free(certStore);
00691             continue;
00692         }
00693 
00694         if (!d->kossl->X509_LOOKUP_load_file(certLookup, _j.toAscii().constData(), X509_FILETYPE_PEM)) {
00695             // error accessing directory and loading pems
00696             kDebug(7029) << "KSSL couldn't read CA root: "
00697                     << _j << endl;
00698             ksslv = KSSLCertificate::ErrorReadingRoot;
00699             d->kossl->X509_STORE_free(certStore);
00700             continue;
00701         }
00702 
00703         // This is the checking code
00704         certStoreCTX = d->kossl->X509_STORE_CTX_new();
00705 
00706         // this is a bad error - could mean no free memory.
00707         // This may be the wrong thing to do here
00708         if (!certStoreCTX) {
00709             kDebug(7029) << "KSSL couldn't create an X509 store context.";
00710             d->kossl->X509_STORE_free(certStore);
00711             continue;
00712         }
00713 
00714         d->kossl->X509_STORE_CTX_init(certStoreCTX, certStore, d->m_cert, NULL);
00715         if (d->_chain.isValid()) {
00716             d->kossl->X509_STORE_CTX_set_chain(certStoreCTX, (STACK_OF(X509)*)d->_chain.rawChain());
00717         }
00718 
00719         //kDebug(7029) << "KSSL setting CRL..............";
00720         // int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x);
00721 
00722         d->kossl->X509_STORE_CTX_set_purpose(certStoreCTX, purposeToOpenSSL(purpose));
00723 
00724         KSSL_X509CallBack_ca = ca ? ca->d->m_cert : 0;
00725         KSSL_X509CallBack_ca_found = false;
00726 
00727         certStoreCTX->error = X509_V_OK;
00728         rc = d->kossl->X509_verify_cert(certStoreCTX);
00729         int errcode = certStoreCTX->error;
00730         if (ca && !KSSL_X509CallBack_ca_found) {
00731             ksslv = KSSLCertificate::Irrelevant;
00732         } else {
00733             ksslv = processError(errcode);
00734         }
00735         // For servers, we can try NS_SSL_SERVER too
00736         if ((ksslv != KSSLCertificate::Ok) &&
00737             (ksslv != KSSLCertificate::Irrelevant) &&
00738             purpose == KSSLCertificate::SSLServer) {
00739             d->kossl->X509_STORE_CTX_set_purpose(certStoreCTX,
00740                                                  X509_PURPOSE_NS_SSL_SERVER);
00741 
00742             certStoreCTX->error = X509_V_OK;
00743             rc = d->kossl->X509_verify_cert(certStoreCTX);
00744             errcode = certStoreCTX->error;
00745             ksslv = processError(errcode);
00746         }
00747         d->kossl->X509_STORE_CTX_free(certStoreCTX);
00748         d->kossl->X509_STORE_free(certStore);
00749         // end of checking code
00750         //
00751 
00752         //kDebug(7029) << "KSSL Validation procedure RC: "
00753         //        << rc << endl;
00754         //kDebug(7029) << "KSSL Validation procedure errcode: "
00755         //        << errcode << endl;
00756         //kDebug(7029) << "KSSL Validation procedure RESULTS: "
00757         //        << ksslv << endl;
00758 
00759         if (ksslv != NoCARoot && ksslv != InvalidCA && ksslv != GetIssuerCertFailed && ksslv != DecodeIssuerPublicKeyFailed && ksslv != GetIssuerCertLocallyFailed ) {
00760             d->m_stateCached = true;
00761             d->m_stateCache = ksslv;
00762         }
00763         break;
00764     }
00765 
00766     if (ksslv != KSSLCertificate::Ok) {
00767         errors << ksslv;
00768     }
00769 #else
00770     errors << KSSLCertificate::NoSSL;
00771 #endif
00772     return errors;
00773 }
00774 
00775 
00776 
00777 KSSLCertificate::KSSLValidation KSSLCertificate::revalidate() {
00778     return revalidate(KSSLCertificate::SSLServer);
00779 }
00780 
00781 
00782 KSSLCertificate::KSSLValidation KSSLCertificate::revalidate(KSSLCertificate::KSSLPurpose p) {
00783     d->m_stateCached = false;
00784     return validate(p);
00785 }
00786 
00787 
00788 KSSLCertificate::KSSLValidation KSSLCertificate::processError(int ec) {
00789     KSSLCertificate::KSSLValidation rc;
00790 
00791     rc = KSSLCertificate::Unknown;
00792 #ifdef KSSL_HAVE_SSL
00793     switch (ec) {
00794 
00795         // see man 1 verify for a detailed listing of all error codes
00796 
00797         // error 0
00798         case X509_V_OK:
00799             rc = KSSLCertificate::Ok;
00800         break;
00801 
00802 
00803         // error 2
00804         case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
00805             rc = KSSLCertificate::GetIssuerCertFailed;
00806         break;
00807 
00808         // error 3
00809         case X509_V_ERR_UNABLE_TO_GET_CRL:
00810             rc = KSSLCertificate::GetCRLFailed;
00811         break;
00812 
00813         // error 4
00814         case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
00815             rc = KSSLCertificate::DecryptCertificateSignatureFailed;
00816         break;
00817 
00818         // error 5
00819         case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
00820             rc = KSSLCertificate::DecryptCRLSignatureFailed;
00821         break;
00822 
00823         // error 6
00824         case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
00825             rc = KSSLCertificate::DecodeIssuerPublicKeyFailed;
00826         break;
00827 
00828         // error 7
00829         case X509_V_ERR_CERT_SIGNATURE_FAILURE:
00830             rc = KSSLCertificate::CertificateSignatureFailed;
00831         break;
00832 
00833         // error 8
00834         case X509_V_ERR_CRL_SIGNATURE_FAILURE:
00835             rc = KSSLCertificate::CRLSignatureFailed;
00836         break;
00837 
00838         // error 9
00839         case X509_V_ERR_CERT_NOT_YET_VALID:
00840             rc = KSSLCertificate::CertificateNotYetValid;
00841         break;
00842 
00843         // error 10
00844         case X509_V_ERR_CERT_HAS_EXPIRED:
00845             rc = KSSLCertificate::CertificateHasExpired;
00846             kDebug(7029) << "KSSL apparently this is expired.  Not after: "
00847                     << getNotAfter() << endl;
00848         break;
00849 
00850         // error 11
00851         case X509_V_ERR_CRL_NOT_YET_VALID:
00852             rc = KSSLCertificate::CRLNotYetValid;
00853         break;
00854 
00855         // error 12
00856         case X509_V_ERR_CRL_HAS_EXPIRED:
00857             rc = KSSLCertificate::CRLHasExpired;
00858         break;
00859 
00860         // error 13
00861         case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
00862             rc = KSSLCertificate::CertificateFieldNotBeforeErroneous;
00863         break;
00864 
00865         // error 14
00866         case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
00867             rc = KSSLCertificate::CertificateFieldNotAfterErroneous;
00868         break;
00869 
00870         // error 15 - unused as of OpenSSL 0.9.8g
00871         case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
00872             rc = KSSLCertificate::CRLFieldLastUpdateErroneous;
00873         break;
00874 
00875         // error 16 - unused as of OpenSSL 0.9.8g
00876         case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
00877             rc = KSSLCertificate::CRLFieldNextUpdateErroneous;
00878         break;
00879 
00880         // error 17
00881         case X509_V_ERR_OUT_OF_MEM:
00882             rc = KSSLCertificate::OutOfMemory;
00883         break;
00884 
00885         // error 18
00886         case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
00887             rc = KSSLCertificate::SelfSigned;
00888         break;
00889 
00890         // error 19
00891         case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
00892             rc = KSSLCertificate::SelfSignedInChain;
00893         break;
00894 
00895         // error 20
00896         case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
00897             rc = KSSLCertificate::GetIssuerCertLocallyFailed;
00898         break;
00899 
00900         // error 21
00901         case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
00902             rc = KSSLCertificate::VerifyLeafSignatureFailed;
00903         break;
00904 
00905         // error 22 - unused as of OpenSSL 0.9.8g
00906         case X509_V_ERR_CERT_CHAIN_TOO_LONG:
00907             rc = KSSLCertificate::CertificateChainTooLong;
00908         break;
00909 
00910         // error 23 - unused as of OpenSSL 0.9.8g
00911         case X509_V_ERR_CERT_REVOKED:
00912             rc = KSSLCertificate::CertificateRevoked;
00913         break;
00914 
00915         // error 24
00916         case X509_V_ERR_INVALID_CA:
00917             rc = KSSLCertificate::InvalidCA;
00918         break;
00919 
00920         // error 25
00921         case X509_V_ERR_PATH_LENGTH_EXCEEDED:
00922             rc = KSSLCertificate::PathLengthExceeded;
00923         break;
00924 
00925         // error 26
00926         case X509_V_ERR_INVALID_PURPOSE:
00927             rc = KSSLCertificate::InvalidPurpose;
00928         break;
00929 
00930         // error 27
00931         case X509_V_ERR_CERT_UNTRUSTED:
00932             rc = KSSLCertificate::CertificateUntrusted;
00933         break;
00934 
00935         // error 28
00936         case X509_V_ERR_CERT_REJECTED:
00937             rc = KSSLCertificate::CertificateRejected;
00938         break;
00939 
00940         // error 29 - only used with -issuer_checks
00941         case X509_V_ERR_SUBJECT_ISSUER_MISMATCH:
00942             rc = KSSLCertificate::IssuerSubjectMismatched;
00943         break;
00944 
00945         // error 30 - only used with -issuer_checks
00946         case X509_V_ERR_AKID_SKID_MISMATCH:
00947             rc = KSSLCertificate::AuthAndSubjectKeyIDMismatched;
00948         break;
00949 
00950         // error 31 - only used with -issuer_checks
00951         case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH:
00952             rc = KSSLCertificate::AuthAndSubjectKeyIDAndNameMismatched;
00953         break;
00954 
00955         // error 32
00956         case X509_V_ERR_KEYUSAGE_NO_CERTSIGN:
00957             rc = KSSLCertificate::KeyMayNotSignCertificate;
00958         break;
00959 
00960 
00961         // error 50 - unused as of OpenSSL 0.9.8g
00962         case X509_V_ERR_APPLICATION_VERIFICATION:
00963             rc = KSSLCertificate::ApplicationVerificationFailed;
00964         break;
00965 
00966 
00967         default:
00968             rc = KSSLCertificate::Unknown;
00969         break;
00970     }
00971 
00972     d->m_stateCache = rc;
00973     d->m_stateCached = true;
00974 #endif
00975     return rc;
00976 }
00977 
00978 
00979 QString KSSLCertificate::getNotBefore() const {
00980 #ifdef KSSL_HAVE_SSL
00981     return ASN1_UTCTIME_QString(X509_get_notBefore(d->m_cert));
00982 #else
00983     return QString();
00984 #endif
00985 }
00986 
00987 
00988 QString KSSLCertificate::getNotAfter() const {
00989 #ifdef KSSL_HAVE_SSL
00990     return ASN1_UTCTIME_QString(X509_get_notAfter(d->m_cert));
00991 #else
00992     return QString();
00993 #endif
00994 }
00995 
00996 
00997 QDateTime KSSLCertificate::getQDTNotBefore() const {
00998 #ifdef KSSL_HAVE_SSL
00999     return ASN1_UTCTIME_QDateTime(X509_get_notBefore(d->m_cert), NULL);
01000 #else
01001     return QDateTime::currentDateTime();
01002 #endif
01003 }
01004 
01005 
01006 QDateTime KSSLCertificate::getQDTNotAfter() const {
01007 #ifdef KSSL_HAVE_SSL
01008     return ASN1_UTCTIME_QDateTime(X509_get_notAfter(d->m_cert), NULL);
01009 #else
01010     return QDateTime::currentDateTime();
01011 #endif
01012 }
01013 
01014 
01015 int operator==(KSSLCertificate &x, KSSLCertificate &y) {
01016 #ifndef KSSL_HAVE_SSL
01017     return 1;
01018 #else
01019     if (!KOSSL::self()->X509_cmp(x.getCert(), y.getCert())) {
01020         return 1;
01021     }
01022     return 0;
01023 #endif
01024 }
01025 
01026 
01027 KSSLCertificate *KSSLCertificate::replicate() {
01028     // The new certificate doesn't have the cached value.  It's probably
01029     // better this way.  We can't anticipate every reason for doing this.
01030     KSSLCertificate *newOne = new KSSLCertificate();
01031 #ifdef KSSL_HAVE_SSL
01032     newOne->setCert(d->kossl->X509_dup(getCert()));
01033     KSSLCertChain *c = d->_chain.replicate();
01034     newOne->setChain(c->rawChain());
01035     delete c;
01036 #endif
01037     return newOne;
01038 }
01039 
01040 
01041 QString KSSLCertificate::toString() 
01042 {
01043     return toDer().toBase64();
01044 }
01045 
01046 
01047 QString KSSLCertificate::verifyText(KSSLValidation x) {
01048     switch (x) {
01049     // messages for errors defined in verify(1)
01050     case KSSLCertificate::Ok:
01051         return i18n("The certificate is valid.");
01052     case KSSLCertificate::GetIssuerCertFailed:
01053         return i18n("Retrieval of the issuer certificate failed. This means the CA's (Certificate Authority) certificate can not be found.");
01054     case KSSLCertificate::GetCRLFailed:
01055         return i18n("Retrieval of the CRL (Certificate Revocation List) failed. This means the CA's (Certificate Authority) CRL can not be found.");
01056     case KSSLCertificate::DecryptCertificateSignatureFailed:
01057         return i18n("The decryption of the certificate's signature failed. This means it could not even be calculated as opposed to just not matching the expected result.");
01058     case KSSLCertificate::DecryptCRLSignatureFailed:
01059         return i18n("The decryption of the CRL's (Certificate Revocation List) signature failed. This means it could not even be calculated as opposed to just not matching the expected result.");
01060     case KSSLCertificate::DecodeIssuerPublicKeyFailed:
01061         return i18n("The decoding of the public key of the issuer failed. This means that the CA's (Certificate Authority) certificate can not be used to verify the certificate you wanted to use.");
01062     case KSSLCertificate::CertificateSignatureFailed:
01063         return i18n("The certificate's signature is invalid. This means that the certificate can not be verified.");
01064     case KSSLCertificate::CRLSignatureFailed:
01065         return i18n("The CRL's (Certificate Revocation List) signature is invalid. This means that the CRL can not be verified.");
01066     case KSSLCertificate::CertificateNotYetValid:
01067         return i18n("The certificate is not valid, yet.");
01068     case KSSLCertificate::CertificateHasExpired:
01069         return i18n("The certificate is not valid, any more.");
01070     case KSSLCertificate::CRLNotYetValid:
01071         return i18n("The CRL (Certificate Revocation List) is not valid, yet.");
01072     case KSSLCertificate::CRLHasExpired:
01073         return i18n("The CRL (Certificate Revocation List) is not valid, yet.");
01074     case KSSLCertificate::CertificateFieldNotBeforeErroneous:
01075         return i18n("The time format of the certificate's 'notBefore' field is invalid.");
01076     case KSSLCertificate::CertificateFieldNotAfterErroneous:
01077         return i18n("The time format of the certificate's 'notAfter' field is invalid.");
01078     case KSSLCertificate::CRLFieldLastUpdateErroneous:
01079         return i18n("The time format of the CRL's (Certificate Revocation List) 'lastUpdate' field is invalid.");
01080     case KSSLCertificate::CRLFieldNextUpdateErroneous:
01081         return i18n("The time format of the CRL's (Certificate Revocation List) 'nextUpdate' field is invalid.");
01082     case KSSLCertificate::OutOfMemory:
01083         return i18n("The OpenSSL process ran out of memory.");
01084     case KSSLCertificate::SelfSigned:
01085         return i18n("The certificate is self-signed and not in the list of trusted certificates. If you want to accept this certificate, import it into the list of trusted certificates.");
01086     case KSSLCertificate::SelfSignedChain:      // this is obsolete and kept around for backwards compatibility, only
01087     case KSSLCertificate::SelfSignedInChain:
01088         return i18n("The certificate is self-signed. While the trust chain could be built up, the root CA's (Certificate Authority) certificate can not be found.");
01089     case KSSLCertificate::GetIssuerCertLocallyFailed:
01090         return i18n("The CA's (Certificate Authority) certificate can not be found. Most likely, your trust chain is broken.");
01091     case KSSLCertificate::VerifyLeafSignatureFailed:
01092         return i18n("The certificate can not be verified as it is the only certificate in the trust chain and not self-signed. If you self-sign the certificate, make sure to import it into the list of trusted certificates.");
01093     case KSSLCertificate::CertificateChainTooLong:
01094         return i18n("The certificate chain is longer than the maximum depth specified.");
01095     case KSSLCertificate::Revoked:     // this is obsolete and kept around for backwards compatibility, only
01096     case KSSLCertificate::CertificateRevoked:
01097         return i18n("The certificate has been revoked.");
01098     case KSSLCertificate::InvalidCA:
01099         return i18n("The certificate's CA (Certificate Authority) is invalid.");
01100     case KSSLCertificate::PathLengthExceeded:
01101         return i18n("The length of the trust chain exceeded one of the CA's (Certificate Authority) 'pathlength' parameters, making all subsequent signatures invalid.");
01102     case KSSLCertificate::InvalidPurpose:
01103         return i18n("The certificate has not been signed for the purpose you tried to use it for. This means the CA (Certificate Authority) does not allow this usage.");
01104     case KSSLCertificate::Untrusted:     // this is obsolete and kept around for backwards compatibility, only
01105     case KSSLCertificate::CertificateUntrusted:
01106         return i18n("The root CA (Certificate Authority) is not trusted for the purpose you tried to use this certificate for.");
01107     case KSSLCertificate::Rejected:     // this is obsolete and kept around for backwards compatibility, only     // this is obsolete and kept around for backwards compatibility, onle
01108     case KSSLCertificate::CertificateRejected:
01109         return i18n("The root CA (Certificate Authority) has been marked to be rejected for the purpose you tried to use it for.");
01110     case KSSLCertificate::IssuerSubjectMismatched:
01111         return i18n("The certificate's CA (Certificate Authority) does not match the CA name of the certificate.");
01112     case KSSLCertificate::AuthAndSubjectKeyIDMismatched:
01113         return i18n("The CA (Certificate Authority) certificate's key ID does not match the key ID in the 'Issuer' section of the certificate you are trying to use.");
01114     case KSSLCertificate::AuthAndSubjectKeyIDAndNameMismatched:
01115         return i18n("The CA (Certificate Authority) certificate's key ID and name do not match the key ID and name in the 'Issuer' section of the certificate you are trying to use.");
01116     case KSSLCertificate::KeyMayNotSignCertificate:
01117         return i18n("The certificate's CA (Certificate Authority) is not allowed to sign certificates.");
01118     case KSSLCertificate::ApplicationVerificationFailed:
01119         return i18n("OpenSSL could not be verified.");
01120 
01121 
01122     // this is obsolete and kept around for backwards compatibility, only
01123     case KSSLCertificate::SignatureFailed:
01124         return i18n("The signature test for this certificate failed. This could mean that the signature of this certificate or any in its trust path are invalid, could not be decoded or that the CRL (Certificate Revocation List) could not be verified. If you see this message, please let the author of the software you are using know that he or she should use the new, more specific error messages.");
01125     case KSSLCertificate::Expired:
01126         return i18n("This certificate, any in its trust path or its CA's (Certificate Authority) CRL (Certificate Revocation List) is not valid. Any of them could not be valid yet or not valid any more. If you see this message, please let the author of the software you are using know that he or she should use the new, more specific error messages.");
01127     // continue 'useful' messages
01128 
01129     // other error messages
01130     case KSSLCertificate::ErrorReadingRoot:
01131     case KSSLCertificate::NoCARoot:
01132         return i18n("Certificate signing authority root files could not be found so the certificate is not verified.");
01133     case KSSLCertificate::NoSSL:
01134         return i18n("SSL support was not found.");
01135     case KSSLCertificate::PrivateKeyFailed:
01136         return i18n("Private key test failed.");
01137     case KSSLCertificate::InvalidHost:
01138         return i18n("The certificate has not been issued for this host.");
01139     case KSSLCertificate::Irrelevant:
01140         return i18n("This certificate is not relevant.");
01141     default:
01142     break;
01143     }
01144 
01145     return i18n("The certificate is invalid.");
01146 }
01147 
01148 
01149 QByteArray KSSLCertificate::toDer() {
01150     QByteArray qba;
01151 #ifdef KSSL_HAVE_SSL
01152     int certlen = d->kossl->i2d_X509(getCert(), NULL);
01153     if (certlen >= 0) {
01154         // These should technically be unsigned char * but it doesn't matter
01155         // for our purposes
01156         char *cert = new char[certlen];
01157         unsigned char *p = (unsigned char *)cert;
01158         // FIXME: return code!
01159         d->kossl->i2d_X509(getCert(), &p);
01160 
01161         // encode it into a QString
01162         qba = QByteArray(cert, certlen);
01163         delete[] cert;
01164     }
01165 #endif
01166     return qba;
01167 }
01168 
01169 
01170 
01171 QByteArray KSSLCertificate::toPem() {
01172 QByteArray qba;
01173 QString thecert = toString();
01174 const char *header = "-----BEGIN CERTIFICATE-----\n";
01175 const char *footer = "-----END CERTIFICATE-----\n";
01176 
01177     // We just do base64 on the ASN1
01178     //  64 character lines  (unpadded)
01179     unsigned int xx = thecert.length() - 1;
01180     for (unsigned int i = 0; i < xx/64; i++) {
01181         thecert.insert(64*(i+1)+i, '\n');
01182     }
01183 
01184     thecert.prepend(header);
01185 
01186     if (thecert[thecert.length()-1] != '\n') {
01187         thecert += '\n';
01188     }
01189 
01190     thecert.append(footer);
01191 
01192     qba = thecert.toLocal8Bit();
01193     return qba;
01194 }
01195 
01196 
01197 #define NETSCAPE_CERT_HDR     "certificate"
01198 
01199 #if OPENSSL_VERSION_NUMBER < 0x00909000L
01200 
01201 typedef struct NETSCAPE_X509_st
01202 {
01203     ASN1_OCTET_STRING *header;
01204     X509 *cert;
01205 } NETSCAPE_X509;
01206 #endif
01207 
01208 // what a piece of crap this is
01209 QByteArray KSSLCertificate::toNetscape() {
01210     QByteArray qba;
01211 #ifdef KSSL_HAVE_SSL
01212     NETSCAPE_X509 nx;
01213     ASN1_OCTET_STRING hdr;
01214     KTemporaryFile ktf;
01215     ktf.open();
01216     FILE *ktf_fs = fopen(ktf.fileName().toAscii(), "r+");
01217 
01218     hdr.data = (unsigned char *)NETSCAPE_CERT_HDR;
01219     hdr.length = strlen(NETSCAPE_CERT_HDR);
01220     nx.header = &hdr;
01221     nx.cert = getCert();
01222 
01223     d->kossl->ASN1_item_i2d_fp(ktf_fs,(unsigned char *)&nx);
01224     fclose(ktf_fs);
01225 
01226     QFile qf(ktf.fileName());
01227     qf.open(QIODevice::ReadOnly);
01228     char *buf = new char[qf.size()];
01229     qf.read(buf, qf.size());
01230     qba = QByteArray(buf, qf.size());
01231     qf.close();
01232     delete[] buf;
01233 
01234 #endif
01235 return qba;
01236 }
01237 
01238 
01239 
01240 QString KSSLCertificate::toText() {
01241     QString text;
01242 #ifdef KSSL_HAVE_SSL
01243     KTemporaryFile ktf;
01244     ktf.open();
01245     FILE *ktf_fs = fopen(ktf.fileName().toAscii(), "r+");
01246 
01247     d->kossl->X509_print(ktf_fs, getCert());
01248     fclose(ktf_fs);
01249 
01250     QFile qf(ktf.fileName());
01251     qf.open(QIODevice::ReadOnly);
01252     char *buf = new char[qf.size()+1];
01253     qf.read(buf, qf.size());
01254     buf[qf.size()] = 0;
01255     text = buf;
01256     delete[] buf;
01257     qf.close();
01258 #endif
01259 return text;
01260 }
01261 
01262 bool KSSLCertificate::setCert(const QString& cert) {
01263 #ifdef KSSL_HAVE_SSL
01264         QByteArray qba, qbb = cert.toLocal8Bit();
01265         qba = QByteArray::fromBase64(qbb);
01266         unsigned char *qbap = reinterpret_cast<unsigned char *>(qba.data());
01267         X509 *x5c = KOSSL::self()->d2i_X509(NULL, &qbap, qba.size());
01268         if (x5c) {
01269             setCert(x5c);
01270             return true;
01271         }
01272 #endif
01273     return false;
01274 }
01275 
01276 
01277 KSSLX509V3& KSSLCertificate::x509V3Extensions() {
01278     return d->_extensions;
01279 }
01280 
01281 
01282 bool KSSLCertificate::isSigner() {
01283     return d->_extensions.certTypeCA();
01284 }
01285 
01286 
01287 QStringList KSSLCertificate::subjAltNames() const {
01288     QStringList rc;
01289 #ifdef KSSL_HAVE_SSL
01290     STACK_OF(GENERAL_NAME) *names;
01291     names = (STACK_OF(GENERAL_NAME)*)d->kossl->X509_get_ext_d2i(d->m_cert, NID_subject_alt_name, 0, 0);
01292 
01293     if (!names) {
01294         return rc;
01295     }
01296 
01297     int cnt = d->kossl->sk_GENERAL_NAME_num(names);
01298 
01299     for (int i = 0; i < cnt; i++) {
01300         const GENERAL_NAME *val = (const GENERAL_NAME *)d->kossl->sk_value(names, i);
01301         if (val->type != GEN_DNS) {
01302             continue;
01303         }
01304 
01305         QString s = (const char *)d->kossl->ASN1_STRING_data(val->d.ia5);
01306         if (!s.isEmpty()) {
01307             rc += s;
01308         }
01309     }
01310     d->kossl->sk_free(names);
01311 #endif
01312     return rc;
01313 }
01314 
01315 
01316 QDataStream& operator<<(QDataStream& s, const KSSLCertificate& r) {
01317     QStringList qsl;
01318     QList<KSSLCertificate *> cl = const_cast<KSSLCertificate&>(r).chain().getChain();
01319 
01320     foreach(KSSLCertificate *c, cl) {
01321         qsl << c->toString();
01322     }
01323 
01324     qDeleteAll(cl);
01325     s << const_cast<KSSLCertificate&>(r).toString() << qsl;
01326 
01327     return s;
01328 }
01329 
01330 
01331 QDataStream& operator>>(QDataStream& s, KSSLCertificate& r) {
01332     QStringList qsl;
01333     QString cert;
01334 
01335     s >> cert >> qsl;
01336 
01337         if (r.setCert(cert) && !qsl.isEmpty()) {
01338             r.chain().setCertChain(qsl);
01339         }
01340 
01341     return s;
01342 }
01343 
01344 
01345 

KIO

Skip menu "KIO"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • KIO
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • Kross
  • KUtils
  • Nepomuk
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal