ksslcertificate.cc

来自「将konqueror浏览器移植到ARM9 2410中」· CC 代码 · 共 643 行 · 第 1/2 页

CC
643
字号
/* This file is part of the KDE project * * Copyright (C) 2000 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., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */#ifdef HAVE_CONFIG_H #include <config.h>#endif#include <unistd.h>#include <qstring.h>#include "kssldefs.h"#include "ksslcertificate.h"#include "ksslcertchain.h"#include "ksslutils.h"#include <kstddirs.h>#include <kmdcodec.h>#include <klocale.h>#include <qdatetime.h>#include <ktempfile.h>#include <sys/types.h>#ifdef HAVE_SYS_STAT_H#include <sys/stat.h>#endif// this hack provided by Malte Starostik to avoid glibc/openssl bug// on some systems#ifdef HAVE_SSL#define crypt _openssl_crypt#include <openssl/ssl.h>#include <openssl/x509.h>#include <openssl/x509v3.h>#include <openssl/x509_vfy.h>#include <openssl/pem.h>#undef crypt#endif#include <kopenssl.h>#include <qcstring.h>#include <kdebug.h>class KSSLCertificatePrivate {public:  KSSLCertificatePrivate() {     kossl = KOSSL::self();  }  ~KSSLCertificatePrivate() {  }  KSSLCertificate::KSSLValidation m_stateCache;  bool m_stateCached;  #ifdef HAVE_SSL    X509 *m_cert;  #endif  KOSSL *kossl;  KSSLCertChain _chain;};KSSLCertificate::KSSLCertificate() {  d = new KSSLCertificatePrivate;  d->m_stateCached = false;  KGlobal::dirs()->addResourceType("kssl", "share/apps/kssl");#ifdef HAVE_SSL  d->m_cert = NULL;#endif}KSSLCertificate::~KSSLCertificate() {#ifdef HAVE_SSL  if (d->m_cert)    d->kossl->X509_free(d->m_cert);#endif  delete d;}KSSLCertChain& KSSLCertificate::chain() {  return d->_chain;}KSSLCertificate *KSSLCertificate::fromString(QCString cert) {KSSLCertificate *n = NULL;#ifdef HAVE_SSL    if (cert.length() == 0) return NULL;    QByteArray qba, qbb = cert.copy();    KCodecs::base64Decode(qbb, qba);    unsigned char *qbap = reinterpret_cast<unsigned char *>(qba.data());    X509 *x5c = KOSSL::self()->d2i_X509(NULL, &qbap, qba.size());    if (!x5c) {       return NULL;    }     n = new KSSLCertificate;    n->setCert(x5c);#endif    return n;}QString KSSLCertificate::getSubject() const {QString rc = "";#ifdef HAVE_SSL  char *t = d->kossl->X509_NAME_oneline(d->kossl->X509_get_subject_name(d->m_cert), 0, 0);  if (!t) return rc;  rc = t;  d->kossl->OPENSSL_free(t);#endifreturn rc;}QString KSSLCertificate::getIssuer() const {QString rc = "";#ifdef HAVE_SSL  char *t = d->kossl->X509_NAME_oneline(d->kossl->X509_get_issuer_name(d->m_cert), 0, 0);  if (!t) return rc;  rc = t;  d->kossl->OPENSSL_free(t);#endifreturn rc;}void KSSLCertificate::setChain(void *c) {#ifdef HAVE_SSL  d->_chain.setChain(c);#endif  d->m_stateCached = false;  d->m_stateCache = KSSLCertificate::Unknown;}void KSSLCertificate::setCert(X509 *c) {#ifdef HAVE_SSL  d->m_cert = c;#endif  d->m_stateCached = false;  d->m_stateCache = KSSLCertificate::Unknown;}X509 *KSSLCertificate::getCert() {#ifdef HAVE_SSL  return d->m_cert;#endifreturn 0;}// pull in the callback.  It's common across multiple files but we want// it to be hidden.#include "ksslcallback.c"bool KSSLCertificate::isValid() {  return (validate() == KSSLCertificate::Ok);}//// See apps/verify.c in OpenSSL for the source of most of this logic.//// CRL files?  we don't do that yet// This is for verifying certificate FILES (.pem), not remote presentations// of certificates.KSSLCertificate::KSSLValidation KSSLCertificate::validate() {#ifdef HAVE_SSL  X509_STORE *certStore;  X509_LOOKUP *certLookup;  X509_STORE_CTX *certStoreCTX;  int rc = 0;  if (!d->m_cert) return KSSLCertificate::Unknown;  if (d->m_stateCached) {    // kdDebug(7029) << "KSSL returning a cached value" << d->m_stateCached << endl;    return d->m_stateCache;  }  QStringList qsl = KGlobal::dirs()->resourceDirs("kssl");  if (qsl.isEmpty()) {    return KSSLCertificate::NoCARoot;  }  KSSLCertificate::KSSLValidation ksslv = Unknown;  for (QValueListIterator<QString> j = qsl.begin();                                   j != qsl.end(); ++j) {    struct stat sb;    QString _j = (*j)+"caroot/ca-bundle.crt";    if (-1 == stat(_j.ascii(), &sb)) continue;    //kdDebug(7029) << "KSSL Certificate Root directory found: " << _j << endl;    certStore = d->kossl->X509_STORE_new();    if (!certStore)      return KSSLCertificate::Unknown;    X509_STORE_set_verify_cb_func(certStore, X509Callback);    certLookup = d->kossl->X509_STORE_add_lookup(certStore, d->kossl->X509_LOOKUP_file());    if (!certLookup) {      // kdDebug(7029) << "KSSL error adding lookup file" << endl;      ksslv = KSSLCertificate::Unknown;      d->kossl->X509_STORE_free(certStore);      continue;    }    //kdDebug(7029) << "KSSL about to load file" << endl;    if (!d->kossl->X509_LOOKUP_load_file(certLookup, _j.ascii(), X509_FILETYPE_PEM)) {      // error accessing directory and loading pems      kdDebug(7029) << "KSSL couldn't read CA root: " << _j << endl;      ksslv = KSSLCertificate::ErrorReadingRoot;      d->kossl->X509_STORE_free(certStore);      continue;    }    //    // This is the checking code    certStoreCTX = d->kossl->X509_STORE_CTX_new();    // this is a bad error - could mean no free memory.  This may be the    // wrong thing to do here    if (!certStoreCTX) {      kdDebug(7029) << "KSSL couldn't create an X509 store context." << endl;      d->kossl->X509_STORE_free(certStore);      continue;    }    //kdDebug(7029) << "KSSL Initializing the certificate store context" << endl;    d->kossl->X509_STORE_CTX_init(certStoreCTX, certStore, d->m_cert, NULL);    if (d->_chain.isValid())      d->kossl->X509_STORE_CTX_set_chain(certStoreCTX, (STACK_OF(X509)*)d->_chain.rawChain());    // FIXME: do all the X509_STORE_CTX_set_flags(); here    //   +----->  Note that this is for 0.9.6 or better ONLY!    d->kossl->X509_STORE_CTX_set_purpose(certStoreCTX, X509_PURPOSE_SSL_SERVER);    //kdDebug(7029) << "KSSL verifying.............." << endl;    certStoreCTX->error = X509_V_OK;    rc = d->kossl->X509_verify_cert(certStoreCTX);    int errcode = certStoreCTX->error;    //kdDebug(7029) << "KSSL freeing" << endl;    d->kossl->X509_STORE_CTX_free(certStoreCTX);    d->kossl->X509_STORE_free(certStore);    // end of checking code    //    ksslv = processError(errcode);    //kdDebug(7029) << "KSSL Validation procedure RC: " << rc << endl;    //kdDebug(7029) << "KSSL Validation procedure errcode: " << errcode << endl;    //kdDebug(7029) << "KSSL Validation procedure RESULTS: " << ksslv << endl;    if (ksslv != NoCARoot && ksslv != InvalidCA) {      d->m_stateCached = true;      d->m_stateCache = ksslv;      break;    }  }  return (d->m_stateCache);#endif  return NoSSL;}KSSLCertificate::KSSLValidation KSSLCertificate::revalidate() {  d->m_stateCached = false;  return validate();}KSSLCertificate::KSSLValidation KSSLCertificate::processError(int ec) {KSSLCertificate::KSSLValidation rc;rc = KSSLCertificate::Unknown;#ifdef HAVE_SSLswitch (ec) {case X509_V_OK:       // OK  rc = KSSLCertificate::Ok;break;case X509_V_ERR_CERT_REJECTED:  rc = KSSLCertificate::Rejected;break;case X509_V_ERR_CERT_UNTRUSTED:  rc = KSSLCertificate::Untrusted;break;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?