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

KIO

  • sources
  • kde-4.14
  • kdelibs
  • kio
  • kssl
ksslcertificate.cpp
Go to the documentation of this file.
1 /* This file is part of the KDE project
2  *
3  * Copyright (C) 2000-2003 George Staikos <staikos@kde.org>
4  * 2008 Richard Hartmann <richih-kde@net.in.tum.de>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public License
17  * along with this library; see the file COPYING.LIB. If not, write to
18  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  */
21 
22 #include "ksslcertificate.h"
23 
24 #include <config.h>
25 #include <ksslconfig.h>
26 
27 
28 
29 #include <unistd.h>
30 #include <QtCore/QString>
31 #include <QtCore/QStringList>
32 #include <QtCore/QFile>
33 
34 #include "kssldefs.h"
35 #include "ksslcertchain.h"
36 #include "ksslutils.h"
37 
38 #include <kstandarddirs.h>
39 #include <kcodecs.h>
40 #include <kde_file.h>
41 #include <klocale.h>
42 #include <QtCore/QDate>
43 #include <ktemporaryfile.h>
44 
45 #include <sys/types.h>
46 
47 #ifdef HAVE_SYS_STAT_H
48 #include <sys/stat.h>
49 #endif
50 
51 // this hack provided by Malte Starostik to avoid glibc/openssl bug
52 // on some systems
53 #ifdef KSSL_HAVE_SSL
54 #define crypt _openssl_crypt
55 #include <openssl/ssl.h>
56 #include <openssl/x509.h>
57 #include <openssl/x509v3.h>
58 #include <openssl/x509_vfy.h>
59 #include <openssl/pem.h>
60 #undef crypt
61 #endif
62 
63 #include <kopenssl.h>
64 #include <kdebug.h>
65 #include "ksslx509v3.h"
66 
67 
68 
69 static char hv[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
70 
71 
72 class KSSLCertificatePrivate {
73 public:
74  KSSLCertificatePrivate() {
75  kossl = KOSSL::self();
76  _lastPurpose = KSSLCertificate::None;
77  }
78 
79  ~KSSLCertificatePrivate() {
80  }
81 
82  KSSLCertificate::KSSLValidation m_stateCache;
83  bool m_stateCached;
84  #ifdef KSSL_HAVE_SSL
85  X509 *m_cert;
86  #endif
87  KOSSL *kossl;
88  KSSLCertChain _chain;
89  KSSLX509V3 _extensions;
90  KSSLCertificate::KSSLPurpose _lastPurpose;
91 };
92 
93 KSSLCertificate::KSSLCertificate() {
94  d = new KSSLCertificatePrivate;
95  d->m_stateCached = false;
96  KGlobal::dirs()->addResourceType("kssl", "data", "kssl");
97  #ifdef KSSL_HAVE_SSL
98  d->m_cert = NULL;
99  #endif
100 }
101 
102 
103 KSSLCertificate::KSSLCertificate(const KSSLCertificate& x) {
104  d = new KSSLCertificatePrivate;
105  d->m_stateCached = false;
106  KGlobal::dirs()->addResourceType("kssl", "data", "kssl");
107  #ifdef KSSL_HAVE_SSL
108  d->m_cert = NULL;
109  setCert(KOSSL::self()->X509_dup(const_cast<KSSLCertificate&>(x).getCert()));
110  KSSLCertChain *c = x.d->_chain.replicate();
111  setChain(c->rawChain());
112  delete c;
113  #endif
114 }
115 
116 
117 
118 KSSLCertificate::~KSSLCertificate() {
119 #ifdef KSSL_HAVE_SSL
120  if (d->m_cert) {
121  d->kossl->X509_free(d->m_cert);
122  }
123 #endif
124  delete d;
125 }
126 
127 
128 KSSLCertChain& KSSLCertificate::chain() {
129  return d->_chain;
130 }
131 
132 
133 KSSLCertificate *KSSLCertificate::fromX509(X509 *x5) {
134  KSSLCertificate *n = NULL;
135 #ifdef KSSL_HAVE_SSL
136  if (x5) {
137  n = new KSSLCertificate;
138  n->setCert(KOSSL::self()->X509_dup(x5));
139  }
140 #endif
141  return n;
142 }
143 
144 
145 KSSLCertificate *KSSLCertificate::fromString(const QByteArray &cert) {
146  KSSLCertificate *n = NULL;
147 #ifdef KSSL_HAVE_SSL
148  if (cert.isEmpty()) {
149  return NULL;
150  }
151 
152  QByteArray qba = QByteArray::fromBase64(cert);
153  unsigned char *qbap = reinterpret_cast<unsigned char *>(qba.data());
154  X509 *x5c = KOSSL::self()->d2i_X509(NULL, &qbap, qba.size());
155  if (!x5c) {
156  return NULL;
157  }
158 
159  n = new KSSLCertificate;
160  n->setCert(x5c);
161 #endif
162  return n;
163 }
164 
165 
166 
167 QString KSSLCertificate::getSubject() const {
168  QString rc = "";
169 
170 #ifdef KSSL_HAVE_SSL
171  char *t = d->kossl->X509_NAME_oneline(d->kossl->X509_get_subject_name(d->m_cert), 0, 0);
172  if (!t) {
173  return rc;
174  }
175  rc = t;
176  d->kossl->OPENSSL_free(t);
177 #endif
178  return rc;
179 }
180 
181 
182 QString KSSLCertificate::getSerialNumber() const {
183  QString rc = "";
184 
185 #ifdef KSSL_HAVE_SSL
186  ASN1_INTEGER *aint = d->kossl->X509_get_serialNumber(d->m_cert);
187  if (aint) {
188  rc = ASN1_INTEGER_QString(aint);
189  // d->kossl->ASN1_INTEGER_free(aint); this makes the sig test fail
190  }
191 #endif
192  return rc;
193 }
194 
195 
196 QString KSSLCertificate::getSignatureText() const {
197  QString rc = "";
198 
199 #ifdef KSSL_HAVE_SSL
200  char *s;
201  int n, i;
202 
203  const X509_ALGOR *algor;
204  const ASN1_BIT_STRING *sig;
205  d->kossl->X509_get0_signature(&sig, &algor, d->m_cert);
206  i = d->kossl->OBJ_obj2nid(algor->algorithm);
207  rc = i18n("Signature Algorithm: ");
208  rc += (i == NID_undef)?i18n("Unknown"):QString(d->kossl->OBJ_nid2ln(i));
209 
210  rc += '\n';
211  rc += i18n("Signature Contents:");
212  n = sig->length;
213  s = (char *)sig->data;
214  for (i = 0; i < n; ++i) {
215  if (i%20 != 0) {
216  rc += ':';
217  }
218  else {
219  rc += '\n';
220  }
221  rc.append(QChar(hv[(s[i]&0xf0)>>4]));
222  rc.append(QChar(hv[s[i]&0x0f]));
223  }
224 
225 #endif
226 
227  return rc;
228 }
229 
230 
231 void KSSLCertificate::getEmails(QStringList &to) const {
232  to.clear();
233 #ifdef KSSL_HAVE_SSL
234  if (!d->m_cert) {
235  return;
236  }
237 
238  STACK *s = d->kossl->X509_get1_email(d->m_cert);
239  const int size = d->kossl->OPENSSL_sk_num(s);
240  if (s) {
241  for(int n=0; n < size; n++) {
242  to.append(d->kossl->OPENSSL_sk_value(s,n));
243  }
244  d->kossl->X509_email_free(s);
245  }
246 #endif
247 }
248 
249 
250 QString KSSLCertificate::getKDEKey() const {
251  return getSubject() + " (" + getMD5DigestText() + ')';
252 }
253 
254 
255 QString KSSLCertificate::getMD5DigestFromKDEKey(const QString &k) {
256  QString rc;
257  int pos = k.lastIndexOf('(');
258  if (pos != -1) {
259  unsigned int len = k.length();
260  if (k.at(len-1) == ')') {
261  rc = k.mid(pos+1, len-pos-2);
262  }
263  }
264  return rc;
265 }
266 
267 
268 QString KSSLCertificate::getMD5DigestText() const {
269 QString rc = "";
270 
271 #ifdef KSSL_HAVE_SSL
272  unsigned int n;
273  unsigned char md[EVP_MAX_MD_SIZE];
274 
275  if (!d->kossl->X509_digest(d->m_cert, d->kossl->EVP_md5(), md, &n)) {
276  return rc;
277  }
278 
279  for (unsigned int j = 0; j < n; j++) {
280  if (j > 0) {
281  rc += ':';
282  }
283  rc.append(QChar(hv[(md[j]&0xf0)>>4]));
284  rc.append(QChar(hv[md[j]&0x0f]));
285  }
286 
287 #endif
288 
289  return rc;
290 }
291 
292 
293 
294 QString KSSLCertificate::getMD5Digest() const {
295 QString rc = "";
296 
297 #ifdef KSSL_HAVE_SSL
298  unsigned int n;
299  unsigned char md[EVP_MAX_MD_SIZE];
300 
301  if (!d->kossl->X509_digest(d->m_cert, d->kossl->EVP_md5(), md, &n)) {
302  return rc;
303  }
304 
305  for (unsigned int j = 0; j < n; j++) {
306  rc.append(QLatin1Char(hv[(md[j]&0xf0)>>4]));
307  rc.append(QLatin1Char(hv[md[j]&0x0f]));
308  }
309 
310 #endif
311 
312  return rc;
313 }
314 
315 
316 
317 QString KSSLCertificate::getKeyType() const {
318 QString rc = "";
319 
320 #ifdef KSSL_HAVE_SSL
321  EVP_PKEY *pkey = d->kossl->X509_get_pubkey(d->m_cert);
322  if (pkey) {
323  #ifndef NO_RSA
324  if (d->kossl->EVP_PKEY_base_id(pkey) == EVP_PKEY_RSA) {
325  rc = "RSA";
326  }
327  else
328  #endif
329  #ifndef NO_DSA
330  if (d->kossl->EVP_PKEY_base_id(pkey) == EVP_PKEY_DSA) {
331  rc = "DSA";
332  }
333  else
334  #endif
335  rc = "Unknown";
336  d->kossl->EVP_PKEY_free(pkey);
337  }
338 #endif
339 
340  return rc;
341 }
342 
343 
344 
345 QString KSSLCertificate::getPublicKeyText() const {
346 QString rc = "";
347 char *x = NULL;
348 
349 #ifdef KSSL_HAVE_SSL
350  EVP_PKEY *pkey = d->kossl->X509_get_pubkey(d->m_cert);
351  if (pkey) {
352  rc = i18nc("Unknown", "Unknown key algorithm");
353  #ifndef NO_RSA
354  if (d->kossl->EVP_PKEY_base_id(pkey) == EVP_PKEY_RSA) {
355  const BIGNUM *n, *e;
356  d->kossl->RSA_get0_key(d->kossl->EVP_PKEY_get0_RSA(pkey), &n, &e, NULL);
357  x = d->kossl->BN_bn2hex(n);
358  rc = i18n("Key type: RSA (%1 bit)", strlen(x)*4) + '\n';
359 
360  rc += i18n("Modulus: ");
361  for (unsigned int i = 0; i < strlen(x); i++) {
362  if (i%40 != 0 && i%2 == 0) {
363  rc += ':';
364  }
365  else if (i%40 == 0) {
366  rc += '\n';
367  }
368  rc += x[i];
369  }
370  rc += '\n';
371  d->kossl->OPENSSL_free(x);
372 
373  x = d->kossl->BN_bn2hex(e);
374  rc += i18n("Exponent: 0x") + QLatin1String(x) +
375  QLatin1String("\n");
376  d->kossl->OPENSSL_free(x);
377  }
378  #endif
379  #ifndef NO_DSA
380  if (d->kossl->EVP_PKEY_base_id(pkey) == EVP_PKEY_DSA) {
381  DSA *dsa = d->kossl->EVP_PKEY_get0_DSA(pkey);
382  const BIGNUM *p, *q, *g;
383  d->kossl->DSA_get0_pqg(dsa, &p, &q, &g);
384  x = d->kossl->BN_bn2hex(p);
385  // hack - this may not be always accurate
386  rc = i18n("Key type: DSA (%1 bit)", strlen(x)*4) + '\n';
387 
388  rc += i18n("Prime: ");
389  for (unsigned int i = 0; i < strlen(x); i++) {
390  if (i%40 != 0 && i%2 == 0) {
391  rc += ':';
392  }
393  else if (i%40 == 0) {
394  rc += '\n';
395  }
396  rc += x[i];
397  }
398  rc += '\n';
399  d->kossl->OPENSSL_free(x);
400 
401  x = d->kossl->BN_bn2hex(q);
402  rc += i18n("160 bit prime factor: ");
403  for (unsigned int i = 0; i < strlen(x); i++) {
404  if (i%40 != 0 && i%2 == 0) {
405  rc += ':';
406  }
407  else if (i%40 == 0) {
408  rc += '\n';
409  }
410  rc += x[i];
411  }
412  rc += '\n';
413  d->kossl->OPENSSL_free(x);
414 
415  x = d->kossl->BN_bn2hex(g);
416  rc += QString("g: ");
417  for (unsigned int i = 0; i < strlen(x); i++) {
418  if (i%40 != 0 && i%2 == 0) {
419  rc += ':';
420  }
421  else if (i%40 == 0) {
422  rc += '\n';
423  }
424  rc += x[i];
425  }
426  rc += '\n';
427  d->kossl->OPENSSL_free(x);
428 
429  const BIGNUM *pub_key;
430  d->kossl->DSA_get0_key(dsa, &pub_key, NULL);
431  x = d->kossl->BN_bn2hex(pub_key);
432  rc += i18n("Public key: ");
433  for (unsigned int i = 0; i < strlen(x); i++) {
434  if (i%40 != 0 && i%2 == 0) {
435  rc += ':';
436  }
437  else if (i%40 == 0) {
438  rc += '\n';
439  }
440  rc += x[i];
441  }
442  rc += '\n';
443  d->kossl->OPENSSL_free(x);
444  }
445  #endif
446  d->kossl->EVP_PKEY_free(pkey);
447  }
448 #endif
449 
450  return rc;
451 }
452 
453 
454 
455 QString KSSLCertificate::getIssuer() const {
456 QString rc = "";
457 
458 #ifdef KSSL_HAVE_SSL
459  char *t = d->kossl->X509_NAME_oneline(d->kossl->X509_get_issuer_name(d->m_cert), 0, 0);
460 
461  if (!t) {
462  return rc;
463  }
464 
465  rc = t;
466  d->kossl->OPENSSL_free(t);
467 #endif
468 
469  return rc;
470 }
471 
472 void KSSLCertificate::setChain(void *c) {
473 #ifdef KSSL_HAVE_SSL
474  d->_chain.setChain(c);
475 #endif
476  d->m_stateCached = false;
477  d->m_stateCache = KSSLCertificate::Unknown;
478 }
479 
480 void KSSLCertificate::setCert(X509 *c) {
481 #ifdef KSSL_HAVE_SSL
482  d->m_cert = c;
483  if (c) {
484  d->_extensions.flags = 0;
485  d->kossl->X509_check_purpose(c, -1, 0); // setup the fields (!!)
486 
487 #if 0
488  kDebug(7029) << "---------------- Certificate ------------------"
489  << endl;
490  kDebug(7029) << getSubject();
491 #endif
492 
493  for (int j = 0; j < d->kossl->X509_PURPOSE_get_count(); j++) {
494  X509_PURPOSE *ptmp = d->kossl->X509_PURPOSE_get0(j);
495  int id = d->kossl->X509_PURPOSE_get_id(ptmp);
496  for (int ca = 0; ca < 2; ca++) {
497  int idret = d->kossl->X509_check_purpose(c, id, ca);
498  if (idret == 1 || idret == 2) { // have it
499  // kDebug() << "PURPOSE: " << id << (ca?" CA":"");
500  if (!ca) {
501  d->_extensions.flags |= (1L <<(id-1));
502  }
503  else d->_extensions.flags |= (1L <<(16+id-1));
504  } else {
505  if (!ca) {
506  d->_extensions.flags &= ~(1L <<(id-1));
507  }
508  else d->_extensions.flags &= ~(1L <<(16+id-1));
509  }
510  }
511  }
512 
513 #if 0
514  kDebug(7029) << "flags: " << QString::number(c->ex_flags, 2)
515  << "\nkeyusage: " << QString::number(c->ex_kusage, 2)
516  << "\nxkeyusage: " << QString::number(c->ex_xkusage, 2)
517  << "\nnscert: " << QString::number(c->ex_nscert, 2)
518  << endl;
519  if (c->ex_flags & EXFLAG_KUSAGE)
520  kDebug(7029) << " --- Key Usage extensions found";
521  else kDebug(7029) << " --- Key Usage extensions NOT found";
522 
523  if (c->ex_flags & EXFLAG_XKUSAGE)
524  kDebug(7029) << " --- Extended key usage extensions found";
525  else kDebug(7029) << " --- Extended key usage extensions NOT found";
526 
527  if (c->ex_flags & EXFLAG_NSCERT)
528  kDebug(7029) << " --- NS extensions found";
529  else kDebug(7029) << " --- NS extensions NOT found";
530 
531  if (d->_extensions.certTypeSSLCA())
532  kDebug(7029) << "NOTE: this is an SSL CA file.";
533  else kDebug(7029) << "NOTE: this is NOT an SSL CA file.";
534 
535  if (d->_extensions.certTypeEmailCA())
536  kDebug(7029) << "NOTE: this is an EMAIL CA file.";
537  else kDebug(7029) << "NOTE: this is NOT an EMAIL CA file.";
538 
539  if (d->_extensions.certTypeCodeCA())
540  kDebug(7029) << "NOTE: this is a CODE CA file.";
541  else kDebug(7029) << "NOTE: this is NOT a CODE CA file.";
542 
543  if (d->_extensions.certTypeSSLClient())
544  kDebug(7029) << "NOTE: this is an SSL client.";
545  else kDebug(7029) << "NOTE: this is NOT an SSL client.";
546 
547  if (d->_extensions.certTypeSSLServer())
548  kDebug(7029) << "NOTE: this is an SSL server.";
549  else kDebug(7029) << "NOTE: this is NOT an SSL server.";
550 
551  if (d->_extensions.certTypeNSSSLServer())
552  kDebug(7029) << "NOTE: this is a NETSCAPE SSL server.";
553  else kDebug(7029) << "NOTE: this is NOT a NETSCAPE SSL server.";
554 
555  if (d->_extensions.certTypeSMIME())
556  kDebug(7029) << "NOTE: this is an SMIME certificate.";
557  else kDebug(7029) << "NOTE: this is NOT an SMIME certificate.";
558 
559  if (d->_extensions.certTypeSMIMEEncrypt())
560  kDebug(7029) << "NOTE: this is an SMIME encrypt cert.";
561  else kDebug(7029) << "NOTE: this is NOT an SMIME encrypt cert.";
562 
563  if (d->_extensions.certTypeSMIMESign())
564  kDebug(7029) << "NOTE: this is an SMIME sign cert.";
565  else kDebug(7029) << "NOTE: this is NOT an SMIME sign cert.";
566 
567  if (d->_extensions.certTypeCRLSign())
568  kDebug(7029) << "NOTE: this is a CRL signer.";
569  else kDebug(7029) << "NOTE: this is NOT a CRL signer.";
570 
571  kDebug(7029) << "-----------------------------------------------"
572  << endl;
573 #endif
574  }
575 #endif
576  d->m_stateCached = false;
577  d->m_stateCache = KSSLCertificate::Unknown;
578 }
579 
580 X509 *KSSLCertificate::getCert() {
581 #ifdef KSSL_HAVE_SSL
582  return d->m_cert;
583 #endif
584  return 0;
585 }
586 
587 // pull in the callback. It's common across multiple files but we want
588 // it to be hidden.
589 
590 #include "ksslcallback.c"
591 
592 
593 bool KSSLCertificate::isValid(KSSLCertificate::KSSLPurpose p) {
594  return (validate(p) == KSSLCertificate::Ok);
595 }
596 
597 
598 bool KSSLCertificate::isValid() {
599  return isValid(KSSLCertificate::SSLServer);
600 }
601 
602 
603 int KSSLCertificate::purposeToOpenSSL(KSSLCertificate::KSSLPurpose p) const {
604  int rc = 0;
605 #ifdef KSSL_HAVE_SSL
606  if (p == KSSLCertificate::SSLServer) {
607  rc = X509_PURPOSE_SSL_SERVER;
608  } else if (p == KSSLCertificate::SSLClient) {
609  rc = X509_PURPOSE_SSL_CLIENT;
610  } else if (p == KSSLCertificate::SMIMEEncrypt) {
611  rc = X509_PURPOSE_SMIME_ENCRYPT;
612  } else if (p == KSSLCertificate::SMIMESign) {
613  rc = X509_PURPOSE_SMIME_SIGN;
614  } else if (p == KSSLCertificate::Any) {
615  rc = X509_PURPOSE_ANY;
616  }
617 #endif
618  return rc;
619 }
620 
621 
622 // For backward compatibility
623 KSSLCertificate::KSSLValidation KSSLCertificate::validate() {
624  return validate(KSSLCertificate::SSLServer);
625 }
626 
627 KSSLCertificate::KSSLValidation KSSLCertificate::validate(KSSLCertificate::KSSLPurpose purpose)
628 {
629  KSSLValidationList result = validateVerbose(purpose);
630  if (result.isEmpty()) {
631  return KSSLCertificate::Ok;
632  }
633  else
634  return result.first();
635 }
636 
637 //
638 // See apps/verify.c in OpenSSL for the source of most of this logic.
639 //
640 
641 // CRL files? we don't do that yet
642 KSSLCertificate::KSSLValidationList KSSLCertificate::validateVerbose(KSSLCertificate::KSSLPurpose purpose)
643 {
644  return validateVerbose(purpose, 0);
645 }
646 
647 KSSLCertificate::KSSLValidationList KSSLCertificate::validateVerbose(KSSLCertificate::KSSLPurpose purpose, KSSLCertificate *ca)
648 {
649  KSSLValidationList errors;
650  if (ca || (d->_lastPurpose != purpose)) {
651  d->m_stateCached = false;
652  }
653 
654  if (!d->m_stateCached) {
655  d->_lastPurpose = purpose;
656  }
657 
658 #ifdef KSSL_HAVE_SSL
659  X509_STORE *certStore;
660  X509_LOOKUP *certLookup;
661  X509_STORE_CTX *certStoreCTX;
662  int rc = 0;
663 
664  if (!d->m_cert) {
665  errors << KSSLCertificate::Unknown;
666  return errors;
667  }
668 
669  if (d->m_stateCached) {
670  errors << d->m_stateCache;
671  return errors;
672  }
673 
674  const QStringList qsl = KGlobal::dirs()->resourceDirs("kssl");
675 
676  if (qsl.isEmpty()) {
677  errors << KSSLCertificate::NoCARoot;
678  return errors;
679  }
680 
681  KSSLCertificate::KSSLValidation ksslv = Unknown;
682 
683  for (QStringList::ConstIterator j = qsl.begin(); j != qsl.end(); ++j) {
684  KDE_struct_stat sb;
685  QString _j = (*j) + "ca-bundle.crt";
686  if (-1 == KDE_stat(_j.toLatin1().constData(), &sb)) {
687  continue;
688  }
689 
690  certStore = d->kossl->X509_STORE_new();
691  if (!certStore) {
692  errors << KSSLCertificate::Unknown;
693  return errors;
694  }
695 
696  d->kossl->X509_STORE_set_verify_cb(certStore, X509Callback);
697 
698  certLookup = d->kossl->X509_STORE_add_lookup(certStore, d->kossl->X509_LOOKUP_file());
699  if (!certLookup) {
700  ksslv = KSSLCertificate::Unknown;
701  d->kossl->X509_STORE_free(certStore);
702  continue;
703  }
704 
705  if (!d->kossl->X509_LOOKUP_load_file(certLookup, _j.toLatin1().constData(), X509_FILETYPE_PEM)) {
706  // error accessing directory and loading pems
707  kDebug(7029) << "KSSL couldn't read CA root: "
708  << _j << endl;
709  ksslv = KSSLCertificate::ErrorReadingRoot;
710  d->kossl->X509_STORE_free(certStore);
711  continue;
712  }
713 
714  // This is the checking code
715  certStoreCTX = d->kossl->X509_STORE_CTX_new();
716 
717  // this is a bad error - could mean no free memory.
718  // This may be the wrong thing to do here
719  if (!certStoreCTX) {
720  kDebug(7029) << "KSSL couldn't create an X509 store context.";
721  d->kossl->X509_STORE_free(certStore);
722  continue;
723  }
724 
725  d->kossl->X509_STORE_CTX_init(certStoreCTX, certStore, d->m_cert, NULL);
726  if (d->_chain.isValid()) {
727  d->kossl->X509_STORE_CTX_set_chain(certStoreCTX, (STACK_OF(X509)*)d->_chain.rawChain());
728  }
729 
730  //kDebug(7029) << "KSSL setting CRL..............";
731  // int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x);
732 
733  d->kossl->X509_STORE_CTX_set_purpose(certStoreCTX, purposeToOpenSSL(purpose));
734 
735  KSSL_X509CallBack_ca = ca ? ca->d->m_cert : 0;
736  KSSL_X509CallBack_ca_found = false;
737 
738  d->kossl->X509_STORE_CTX_set_error(certStoreCTX, X509_V_OK);
739  rc = d->kossl->X509_verify_cert(certStoreCTX);
740  int errcode = d->kossl->X509_STORE_CTX_get_error(certStoreCTX);
741  if (ca && !KSSL_X509CallBack_ca_found) {
742  ksslv = KSSLCertificate::Irrelevant;
743  } else {
744  ksslv = processError(errcode);
745  }
746  // For servers, we can try NS_SSL_SERVER too
747  if ((ksslv != KSSLCertificate::Ok) &&
748  (ksslv != KSSLCertificate::Irrelevant) &&
749  purpose == KSSLCertificate::SSLServer) {
750  d->kossl->X509_STORE_CTX_set_purpose(certStoreCTX,
751  X509_PURPOSE_NS_SSL_SERVER);
752 
753  d->kossl->X509_STORE_CTX_set_error(certStoreCTX, X509_V_OK);
754  rc = d->kossl->X509_verify_cert(certStoreCTX);
755  errcode = d->kossl->X509_STORE_CTX_get_error(certStoreCTX);
756  ksslv = processError(errcode);
757  }
758  d->kossl->X509_STORE_CTX_free(certStoreCTX);
759  d->kossl->X509_STORE_free(certStore);
760  // end of checking code
761  //
762 
763  //kDebug(7029) << "KSSL Validation procedure RC: "
764  // << rc << endl;
765  //kDebug(7029) << "KSSL Validation procedure errcode: "
766  // << errcode << endl;
767  //kDebug(7029) << "KSSL Validation procedure RESULTS: "
768  // << ksslv << endl;
769 
770  if (ksslv != NoCARoot && ksslv != InvalidCA && ksslv != GetIssuerCertFailed && ksslv != DecodeIssuerPublicKeyFailed && ksslv != GetIssuerCertLocallyFailed ) {
771  d->m_stateCached = true;
772  d->m_stateCache = ksslv;
773  }
774  break;
775  }
776 
777  if (ksslv != KSSLCertificate::Ok) {
778  errors << ksslv;
779  }
780 #else
781  errors << KSSLCertificate::NoSSL;
782 #endif
783  return errors;
784 }
785 
786 
787 
788 KSSLCertificate::KSSLValidation KSSLCertificate::revalidate() {
789  return revalidate(KSSLCertificate::SSLServer);
790 }
791 
792 
793 KSSLCertificate::KSSLValidation KSSLCertificate::revalidate(KSSLCertificate::KSSLPurpose p) {
794  d->m_stateCached = false;
795  return validate(p);
796 }
797 
798 
799 KSSLCertificate::KSSLValidation KSSLCertificate::processError(int ec) {
800  KSSLCertificate::KSSLValidation rc;
801 
802  rc = KSSLCertificate::Unknown;
803 #ifdef KSSL_HAVE_SSL
804  switch (ec) {
805 
806  // see man 1 verify for a detailed listing of all error codes
807 
808  // error 0
809  case X509_V_OK:
810  rc = KSSLCertificate::Ok;
811  break;
812 
813 
814  // error 2
815  case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
816  rc = KSSLCertificate::GetIssuerCertFailed;
817  break;
818 
819  // error 3
820  case X509_V_ERR_UNABLE_TO_GET_CRL:
821  rc = KSSLCertificate::GetCRLFailed;
822  break;
823 
824  // error 4
825  case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
826  rc = KSSLCertificate::DecryptCertificateSignatureFailed;
827  break;
828 
829  // error 5
830  case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
831  rc = KSSLCertificate::DecryptCRLSignatureFailed;
832  break;
833 
834  // error 6
835  case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
836  rc = KSSLCertificate::DecodeIssuerPublicKeyFailed;
837  break;
838 
839  // error 7
840  case X509_V_ERR_CERT_SIGNATURE_FAILURE:
841  rc = KSSLCertificate::CertificateSignatureFailed;
842  break;
843 
844  // error 8
845  case X509_V_ERR_CRL_SIGNATURE_FAILURE:
846  rc = KSSLCertificate::CRLSignatureFailed;
847  break;
848 
849  // error 9
850  case X509_V_ERR_CERT_NOT_YET_VALID:
851  rc = KSSLCertificate::CertificateNotYetValid;
852  break;
853 
854  // error 10
855  case X509_V_ERR_CERT_HAS_EXPIRED:
856  rc = KSSLCertificate::CertificateHasExpired;
857  kDebug(7029) << "KSSL apparently this is expired. Not after: "
858  << getNotAfter() << endl;
859  break;
860 
861  // error 11
862  case X509_V_ERR_CRL_NOT_YET_VALID:
863  rc = KSSLCertificate::CRLNotYetValid;
864  break;
865 
866  // error 12
867  case X509_V_ERR_CRL_HAS_EXPIRED:
868  rc = KSSLCertificate::CRLHasExpired;
869  break;
870 
871  // error 13
872  case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
873  rc = KSSLCertificate::CertificateFieldNotBeforeErroneous;
874  break;
875 
876  // error 14
877  case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
878  rc = KSSLCertificate::CertificateFieldNotAfterErroneous;
879  break;
880 
881  // error 15 - unused as of OpenSSL 0.9.8g
882  case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
883  rc = KSSLCertificate::CRLFieldLastUpdateErroneous;
884  break;
885 
886  // error 16 - unused as of OpenSSL 0.9.8g
887  case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
888  rc = KSSLCertificate::CRLFieldNextUpdateErroneous;
889  break;
890 
891  // error 17
892  case X509_V_ERR_OUT_OF_MEM:
893  rc = KSSLCertificate::OutOfMemory;
894  break;
895 
896  // error 18
897  case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
898  rc = KSSLCertificate::SelfSigned;
899  break;
900 
901  // error 19
902  case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
903  rc = KSSLCertificate::SelfSignedInChain;
904  break;
905 
906  // error 20
907  case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
908  rc = KSSLCertificate::GetIssuerCertLocallyFailed;
909  break;
910 
911  // error 21
912  case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
913  rc = KSSLCertificate::VerifyLeafSignatureFailed;
914  break;
915 
916  // error 22 - unused as of OpenSSL 0.9.8g
917  case X509_V_ERR_CERT_CHAIN_TOO_LONG:
918  rc = KSSLCertificate::CertificateChainTooLong;
919  break;
920 
921  // error 23 - unused as of OpenSSL 0.9.8g
922  case X509_V_ERR_CERT_REVOKED:
923  rc = KSSLCertificate::CertificateRevoked;
924  break;
925 
926  // error 24
927  case X509_V_ERR_INVALID_CA:
928  rc = KSSLCertificate::InvalidCA;
929  break;
930 
931  // error 25
932  case X509_V_ERR_PATH_LENGTH_EXCEEDED:
933  rc = KSSLCertificate::PathLengthExceeded;
934  break;
935 
936  // error 26
937  case X509_V_ERR_INVALID_PURPOSE:
938  rc = KSSLCertificate::InvalidPurpose;
939  break;
940 
941  // error 27
942  case X509_V_ERR_CERT_UNTRUSTED:
943  rc = KSSLCertificate::CertificateUntrusted;
944  break;
945 
946  // error 28
947  case X509_V_ERR_CERT_REJECTED:
948  rc = KSSLCertificate::CertificateRejected;
949  break;
950 
951  // error 29 - only used with -issuer_checks
952  case X509_V_ERR_SUBJECT_ISSUER_MISMATCH:
953  rc = KSSLCertificate::IssuerSubjectMismatched;
954  break;
955 
956  // error 30 - only used with -issuer_checks
957  case X509_V_ERR_AKID_SKID_MISMATCH:
958  rc = KSSLCertificate::AuthAndSubjectKeyIDMismatched;
959  break;
960 
961  // error 31 - only used with -issuer_checks
962  case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH:
963  rc = KSSLCertificate::AuthAndSubjectKeyIDAndNameMismatched;
964  break;
965 
966  // error 32
967  case X509_V_ERR_KEYUSAGE_NO_CERTSIGN:
968  rc = KSSLCertificate::KeyMayNotSignCertificate;
969  break;
970 
971 
972  // error 50 - unused as of OpenSSL 0.9.8g
973  case X509_V_ERR_APPLICATION_VERIFICATION:
974  rc = KSSLCertificate::ApplicationVerificationFailed;
975  break;
976 
977 
978  default:
979  rc = KSSLCertificate::Unknown;
980  break;
981  }
982 
983  d->m_stateCache = rc;
984  d->m_stateCached = true;
985 #endif
986  return rc;
987 }
988 
989 
990 QString KSSLCertificate::getNotBefore() const {
991 #ifdef KSSL_HAVE_SSL
992  return ASN1_UTCTIME_QString(d->kossl->X509_getm_notBefore(d->m_cert));
993 #else
994  return QString();
995 #endif
996 }
997 
998 
999 QString KSSLCertificate::getNotAfter() const {
1000 #ifdef KSSL_HAVE_SSL
1001  return ASN1_UTCTIME_QString(d->kossl->X509_getm_notAfter(d->m_cert));
1002 #else
1003  return QString();
1004 #endif
1005 }
1006 
1007 
1008 QDateTime KSSLCertificate::getQDTNotBefore() const {
1009 #ifdef KSSL_HAVE_SSL
1010  return ASN1_UTCTIME_QDateTime(d->kossl->X509_getm_notBefore(d->m_cert), NULL);
1011 #else
1012  return QDateTime::currentDateTime();
1013 #endif
1014 }
1015 
1016 
1017 QDateTime KSSLCertificate::getQDTNotAfter() const {
1018 #ifdef KSSL_HAVE_SSL
1019  return ASN1_UTCTIME_QDateTime(d->kossl->X509_getm_notAfter(d->m_cert), NULL);
1020 #else
1021  return QDateTime::currentDateTime();
1022 #endif
1023 }
1024 
1025 
1026 int operator==(KSSLCertificate &x, KSSLCertificate &y) {
1027 #ifndef KSSL_HAVE_SSL
1028  return 1;
1029 #else
1030  if (!KOSSL::self()->X509_cmp(x.getCert(), y.getCert())) {
1031  return 1;
1032  }
1033  return 0;
1034 #endif
1035 }
1036 
1037 
1038 KSSLCertificate *KSSLCertificate::replicate() {
1039  // The new certificate doesn't have the cached value. It's probably
1040  // better this way. We can't anticipate every reason for doing this.
1041  KSSLCertificate *newOne = new KSSLCertificate();
1042 #ifdef KSSL_HAVE_SSL
1043  newOne->setCert(d->kossl->X509_dup(getCert()));
1044  KSSLCertChain *c = d->_chain.replicate();
1045  newOne->setChain(c->rawChain());
1046  delete c;
1047 #endif
1048  return newOne;
1049 }
1050 
1051 
1052 QString KSSLCertificate::toString()
1053 {
1054  return toDer().toBase64();
1055 }
1056 
1057 
1058 QString KSSLCertificate::verifyText(KSSLValidation x) {
1059  switch (x) {
1060  // messages for errors defined in verify(1)
1061  case KSSLCertificate::Ok:
1062  return i18n("The certificate is valid.");
1063  case KSSLCertificate::GetIssuerCertFailed:
1064  return i18n("Retrieval of the issuer certificate failed. This means the CA's (Certificate Authority) certificate can not be found.");
1065  case KSSLCertificate::GetCRLFailed:
1066  return i18n("Retrieval of the CRL (Certificate Revocation List) failed. This means the CA's (Certificate Authority) CRL can not be found.");
1067  case KSSLCertificate::DecryptCertificateSignatureFailed:
1068  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.");
1069  case KSSLCertificate::DecryptCRLSignatureFailed:
1070  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.");
1071  case KSSLCertificate::DecodeIssuerPublicKeyFailed:
1072  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.");
1073  case KSSLCertificate::CertificateSignatureFailed:
1074  return i18n("The certificate's signature is invalid. This means that the certificate can not be verified.");
1075  case KSSLCertificate::CRLSignatureFailed:
1076  return i18n("The CRL's (Certificate Revocation List) signature is invalid. This means that the CRL can not be verified.");
1077  case KSSLCertificate::CertificateNotYetValid:
1078  return i18n("The certificate is not valid, yet.");
1079  case KSSLCertificate::CertificateHasExpired:
1080  return i18n("The certificate is not valid, any more.");
1081  case KSSLCertificate::CRLNotYetValid:
1082  return i18n("The CRL (Certificate Revocation List) is not valid, yet.");
1083  case KSSLCertificate::CRLHasExpired:
1084  return i18n("The CRL (Certificate Revocation List) is not valid, yet.");
1085  case KSSLCertificate::CertificateFieldNotBeforeErroneous:
1086  return i18n("The time format of the certificate's 'notBefore' field is invalid.");
1087  case KSSLCertificate::CertificateFieldNotAfterErroneous:
1088  return i18n("The time format of the certificate's 'notAfter' field is invalid.");
1089  case KSSLCertificate::CRLFieldLastUpdateErroneous:
1090  return i18n("The time format of the CRL's (Certificate Revocation List) 'lastUpdate' field is invalid.");
1091  case KSSLCertificate::CRLFieldNextUpdateErroneous:
1092  return i18n("The time format of the CRL's (Certificate Revocation List) 'nextUpdate' field is invalid.");
1093  case KSSLCertificate::OutOfMemory:
1094  return i18n("The OpenSSL process ran out of memory.");
1095  case KSSLCertificate::SelfSigned:
1096  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.");
1097  case KSSLCertificate::SelfSignedChain: // this is obsolete and kept around for backwards compatibility, only
1098  case KSSLCertificate::SelfSignedInChain:
1099  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.");
1100  case KSSLCertificate::GetIssuerCertLocallyFailed:
1101  return i18n("The CA's (Certificate Authority) certificate can not be found. Most likely, your trust chain is broken.");
1102  case KSSLCertificate::VerifyLeafSignatureFailed:
1103  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.");
1104  case KSSLCertificate::CertificateChainTooLong:
1105  return i18n("The certificate chain is longer than the maximum depth specified.");
1106  case KSSLCertificate::Revoked: // this is obsolete and kept around for backwards compatibility, only
1107  case KSSLCertificate::CertificateRevoked:
1108  return i18n("The certificate has been revoked.");
1109  case KSSLCertificate::InvalidCA:
1110  return i18n("The certificate's CA (Certificate Authority) is invalid.");
1111  case KSSLCertificate::PathLengthExceeded:
1112  return i18n("The length of the trust chain exceeded one of the CA's (Certificate Authority) 'pathlength' parameters, making all subsequent signatures invalid.");
1113  case KSSLCertificate::InvalidPurpose:
1114  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.");
1115  case KSSLCertificate::Untrusted: // this is obsolete and kept around for backwards compatibility, only
1116  case KSSLCertificate::CertificateUntrusted:
1117  return i18n("The root CA (Certificate Authority) is not trusted for the purpose you tried to use this certificate for.");
1118  case KSSLCertificate::Rejected: // this is obsolete and kept around for backwards compatibility, only // this is obsolete and kept around for backwards compatibility, onle
1119  case KSSLCertificate::CertificateRejected:
1120  return i18n("The root CA (Certificate Authority) has been marked to be rejected for the purpose you tried to use it for.");
1121  case KSSLCertificate::IssuerSubjectMismatched:
1122  return i18n("The certificate's CA (Certificate Authority) does not match the CA name of the certificate.");
1123  case KSSLCertificate::AuthAndSubjectKeyIDMismatched:
1124  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.");
1125  case KSSLCertificate::AuthAndSubjectKeyIDAndNameMismatched:
1126  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.");
1127  case KSSLCertificate::KeyMayNotSignCertificate:
1128  return i18n("The certificate's CA (Certificate Authority) is not allowed to sign certificates.");
1129  case KSSLCertificate::ApplicationVerificationFailed:
1130  return i18n("OpenSSL could not be verified.");
1131 
1132 
1133  // this is obsolete and kept around for backwards compatibility, only
1134  case KSSLCertificate::SignatureFailed:
1135  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.");
1136  case KSSLCertificate::Expired:
1137  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.");
1138  // continue 'useful' messages
1139 
1140  // other error messages
1141  case KSSLCertificate::ErrorReadingRoot:
1142  case KSSLCertificate::NoCARoot:
1143  return i18n("Certificate signing authority root files could not be found so the certificate is not verified.");
1144  case KSSLCertificate::NoSSL:
1145  return i18n("SSL support was not found.");
1146  case KSSLCertificate::PrivateKeyFailed:
1147  return i18n("Private key test failed.");
1148  case KSSLCertificate::InvalidHost:
1149  return i18n("The certificate has not been issued for this host.");
1150  case KSSLCertificate::Irrelevant:
1151  return i18n("This certificate is not relevant.");
1152  default:
1153  break;
1154  }
1155 
1156  return i18n("The certificate is invalid.");
1157 }
1158 
1159 
1160 QByteArray KSSLCertificate::toDer() {
1161  QByteArray qba;
1162 #ifdef KSSL_HAVE_SSL
1163  int certlen = d->kossl->i2d_X509(getCert(), NULL);
1164  if (certlen >= 0) {
1165  // These should technically be unsigned char * but it doesn't matter
1166  // for our purposes
1167  char *cert = new char[certlen];
1168  unsigned char *p = (unsigned char *)cert;
1169  // FIXME: return code!
1170  d->kossl->i2d_X509(getCert(), &p);
1171 
1172  // encode it into a QString
1173  qba = QByteArray(cert, certlen);
1174  delete[] cert;
1175  }
1176 #endif
1177  return qba;
1178 }
1179 
1180 
1181 
1182 QByteArray KSSLCertificate::toPem() {
1183 QByteArray qba;
1184 QString thecert = toString();
1185 const char *header = "-----BEGIN CERTIFICATE-----\n";
1186 const char *footer = "-----END CERTIFICATE-----\n";
1187 
1188  // We just do base64 on the ASN1
1189  // 64 character lines (unpadded)
1190  unsigned int xx = thecert.length() - 1;
1191  for (unsigned int i = 0; i < xx/64; i++) {
1192  thecert.insert(64*(i+1)+i, '\n');
1193  }
1194 
1195  thecert.prepend(header);
1196 
1197  if (thecert[thecert.length()-1] != '\n') {
1198  thecert += '\n';
1199  }
1200 
1201  thecert.append(footer);
1202 
1203  qba = thecert.toLocal8Bit();
1204  return qba;
1205 }
1206 
1207 
1208 #define NETSCAPE_CERT_HDR "certificate"
1209 
1210 #ifdef KSSL_HAVE_SSL
1211 #if OPENSSL_VERSION_NUMBER < 0x00909000L
1212 
1213 typedef struct NETSCAPE_X509_st
1214 {
1215  ASN1_OCTET_STRING *header;
1216  X509 *cert;
1217 } NETSCAPE_X509;
1218 #endif
1219 #endif
1220 
1221 // what a piece of crap this is
1222 QByteArray KSSLCertificate::toNetscape() {
1223  QByteArray qba;
1224  // no equivalent in OpenSSL 1.1.0 (?), so behave as if we had no OpenSSL at all
1225 #if KSSL_HAVE_SSL && OPENSSL_VERSION_NUMBER < 0x10100000L
1226  NETSCAPE_X509 nx;
1227  ASN1_OCTET_STRING hdr;
1228  KTemporaryFile ktf;
1229  ktf.open();
1230  FILE *ktf_fs = fopen(ktf.fileName().toLatin1(), "r+");
1231 
1232  hdr.data = (unsigned char *)NETSCAPE_CERT_HDR;
1233  hdr.length = strlen(NETSCAPE_CERT_HDR);
1234  nx.header = &hdr;
1235  nx.cert = getCert();
1236 
1237  d->kossl->ASN1_item_i2d_fp(ktf_fs,(unsigned char *)&nx);
1238  fclose(ktf_fs);
1239 
1240  QFile qf(ktf.fileName());
1241  if (qf.open(QIODevice::ReadOnly)) {
1242  qba = qf.readAll();
1243  }
1244 #endif
1245 return qba;
1246 }
1247 
1248 
1249 
1250 QString KSSLCertificate::toText() {
1251  QString text;
1252 #ifdef KSSL_HAVE_SSL
1253  KTemporaryFile ktf;
1254  ktf.open();
1255  FILE *ktf_fs = fopen(ktf.fileName().toLatin1(), "r+");
1256 
1257  d->kossl->X509_print(ktf_fs, getCert());
1258  fclose(ktf_fs);
1259 
1260  QFile qf(ktf.fileName());
1261  if (!qf.open(QIODevice::ReadOnly) )
1262  return text;
1263  char *buf = new char[qf.size()+1];
1264  qf.read(buf, qf.size());
1265  buf[qf.size()] = 0;
1266  text = buf;
1267  delete[] buf;
1268  qf.close();
1269 #endif
1270 return text;
1271 }
1272 
1273 bool KSSLCertificate::setCert(const QString& cert) {
1274 #ifdef KSSL_HAVE_SSL
1275  QByteArray qba, qbb = cert.toLocal8Bit();
1276  qba = QByteArray::fromBase64(qbb);
1277  unsigned char *qbap = reinterpret_cast<unsigned char *>(qba.data());
1278  X509 *x5c = KOSSL::self()->d2i_X509(NULL, &qbap, qba.size());
1279  if (x5c) {
1280  setCert(x5c);
1281  return true;
1282  }
1283 #endif
1284  return false;
1285 }
1286 
1287 
1288 KSSLX509V3& KSSLCertificate::x509V3Extensions() {
1289  return d->_extensions;
1290 }
1291 
1292 
1293 bool KSSLCertificate::isSigner() {
1294  return d->_extensions.certTypeCA();
1295 }
1296 
1297 
1298 QStringList KSSLCertificate::subjAltNames() const {
1299  QStringList rc;
1300 #ifdef KSSL_HAVE_SSL
1301  STACK_OF(GENERAL_NAME) *names;
1302  names = (STACK_OF(GENERAL_NAME)*)d->kossl->X509_get_ext_d2i(d->m_cert, NID_subject_alt_name, 0, 0);
1303 
1304  if (!names) {
1305  return rc;
1306  }
1307 
1308  int cnt = d->kossl->OPENSSL_sk_num((STACK *)names);
1309 
1310  for (int i = 0; i < cnt; i++) {
1311  const GENERAL_NAME *val = (const GENERAL_NAME *)d->kossl->OPENSSL_sk_value(names, i);
1312  if (val->type != GEN_DNS) {
1313  continue;
1314  }
1315 
1316  QString s = (const char *)d->kossl->ASN1_STRING_data(val->d.ia5);
1317  if (!s.isEmpty() &&
1318  /* skip subjectAltNames with embedded NULs */
1319  s.length() == d->kossl->ASN1_STRING_length(val->d.ia5)) {
1320  rc += s;
1321  }
1322  }
1323  d->kossl->OPENSSL_sk_free(names);
1324 #endif
1325  return rc;
1326 }
1327 
1328 
1329 QDataStream& operator<<(QDataStream& s, const KSSLCertificate& r) {
1330  QStringList qsl;
1331  QList<KSSLCertificate *> cl = const_cast<KSSLCertificate&>(r).chain().getChain();
1332 
1333  foreach(KSSLCertificate *c, cl) {
1334  qsl << c->toString();
1335  }
1336 
1337  qDeleteAll(cl);
1338  s << const_cast<KSSLCertificate&>(r).toString() << qsl;
1339 
1340  return s;
1341 }
1342 
1343 
1344 QDataStream& operator>>(QDataStream& s, KSSLCertificate& r) {
1345  QStringList qsl;
1346  QString cert;
1347 
1348  s >> cert >> qsl;
1349 
1350  if (r.setCert(cert) && !qsl.isEmpty()) {
1351  r.chain().setCertChain(qsl);
1352  }
1353 
1354  return s;
1355 }
1356 
1357 
1358 
operator>>
QDataStream & operator>>(QDataStream &s, KSSLCertificate &r)
Definition: ksslcertificate.cpp:1344
KSSLCertificate::Expired
Definition: ksslcertificate.h:120
i18n
QString i18n(const char *text)
QList::clear
void clear()
KSSLCertificate::DecryptCRLSignatureFailed
Definition: ksslcertificate.h:137
KSSLCertificate::replicate
KSSLCertificate * replicate()
Explicitly make a copy of this certificate.
Definition: ksslcertificate.cpp:1038
QString::append
QString & append(QChar ch)
KSSLCertificate::PathLengthExceeded
Definition: ksslcertificate.h:120
KSSLCertificate::Unknown
Definition: ksslcertificate.h:119
header
const char header[]
KSSLCertificate::CRLNotYetValid
Definition: ksslcertificate.h:128
kssldefs.h
KSSLCertificate::AuthAndSubjectKeyIDMismatched
Definition: ksslcertificate.h:140
KSSLCertificate::CertificateUntrusted
Definition: ksslcertificate.h:134
kdebug.h
KSSLCertificate::Untrusted
Definition: ksslcertificate.h:122
NETSCAPE_CERT_HDR
#define NETSCAPE_CERT_HDR
Definition: ksslcertificate.cpp:1208
KSSLCertificate::NoCARoot
Definition: ksslcertificate.h:119
KStandardDirs::addResourceType
bool addResourceType(const char *type, const QString &relativename, bool priority=true)
KSSLCertificate::validate
KSSLValidation validate()
Check if this is a valid certificate.
Definition: ksslcertificate.cpp:623
KSSLCertificate::getSerialNumber
QString getSerialNumber() const
Get the serial number of the certificate.
Definition: ksslcertificate.cpp:182
KSSLCertificate::DecodeIssuerPublicKeyFailed
Definition: ksslcertificate.h:125
KSSLCertificate::InvalidPurpose
Definition: ksslcertificate.h:119
QByteArray
KSSLCertificate::Any
Definition: ksslcertificate.h:147
KSSLCertificate::x509V3Extensions
KSSLX509V3 & x509V3Extensions()
Access the X.509v3 parameters.
Definition: ksslcertificate.cpp:1288
KSSLCertificate::CertificateNotYetValid
Definition: ksslcertificate.h:127
KSSLCertificate::PrivateKeyFailed
Definition: ksslcertificate.h:123
KSSLCertificate::chain
KSSLCertChain & chain()
Get a reference to the certificate chain.
Definition: ksslcertificate.cpp:128
QDataStream
QChar
KSSLCertificate::Revoked
Definition: ksslcertificate.h:122
KSSLCertificate::toNetscape
QByteArray toNetscape()
Convert the certificate to Netscape format.
Definition: ksslcertificate.cpp:1222
QString::prepend
QString & prepend(QChar ch)
ksslcertificate.h
KSSLCertificate::CertificateHasExpired
Definition: ksslcertificate.h:127
KSSLCertificate::SignatureFailed
Definition: ksslcertificate.h:122
KSSLCertificate::KeyMayNotSignCertificate
Definition: ksslcertificate.h:142
KSSLCertificate::OutOfMemory
Definition: ksslcertificate.h:140
KSSLCertificate::VerifyLeafSignatureFailed
Definition: ksslcertificate.h:134
KSSLCertificate::CRLHasExpired
Definition: ksslcertificate.h:128
KGlobal::dirs
KStandardDirs * dirs()
QByteArray::isEmpty
bool isEmpty() const
KSSLCertificate::CertificateFieldNotAfterErroneous
Definition: ksslcertificate.h:130
KSSLCertificate
KDE X.509 Certificate.
Definition: ksslcertificate.h:74
KSSLCertificate::revalidate
KSSLValidation revalidate()
Check if this is a valid certificate.
Definition: ksslcertificate.cpp:788
KSSLCertificate::IssuerSubjectMismatched
Definition: ksslcertificate.h:143
KSSLCertificate::getIssuer
QString getIssuer() const
Get the issuer of the certificate (X.509 map).
Definition: ksslcertificate.cpp:455
KTemporaryFile
KSSLCertificate::getPublicKeyText
QString getPublicKeyText() const
Get the public key.
Definition: ksslcertificate.cpp:345
KSSLCertChain::rawChain
void * rawChain()
Read the raw chain in OpenSSL format.
Definition: ksslcertchain.cpp:104
KSSLCertificate::SelfSigned
Definition: ksslcertificate.h:121
kDebug
static QDebug kDebug(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
KSSLCertificate::getSubject
QString getSubject() const
Get the subject of the certificate (X.509 map).
Definition: ksslcertificate.cpp:167
KSSLCertificate::getMD5DigestText
QString getMD5DigestText() const
Get the MD5 digest of the certificate.
Definition: ksslcertificate.cpp:268
klocale.h
KSSLCertificate::getQDTNotAfter
QDateTime getQDTNotAfter() const
Get the date that the certificate is valid until.
Definition: ksslcertificate.cpp:1017
KSSLCertificate::ErrorReadingRoot
Definition: ksslcertificate.h:121
QFile
KSSLCertificate::Ok
Definition: ksslcertificate.h:119
i18nc
QString i18nc(const char *ctxt, const char *text)
QString::lastIndexOf
int lastIndexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
KSSLCertificate::GetCRLFailed
Definition: ksslcertificate.h:141
KSSLCertificate::Rejected
Definition: ksslcertificate.h:123
KSSLCertificate::None
Definition: ksslcertificate.h:146
KSSLCertChain
KDE Certificate Chain Representation Class.
Definition: ksslcertchain.h:43
KSSLCertificate::getQDTNotBefore
QDateTime getQDTNotBefore() const
Get the date that the certificate becomes valid on.
Definition: ksslcertificate.cpp:1008
KSSLCertificate::verifyText
static QString verifyText(KSSLValidation x)
Obtain the localized message that corresponds to a validation result.
Definition: ksslcertificate.cpp:1058
KSSLCertificate::getCert
X509 * getCert()
Definition: ksslcertificate.cpp:580
KSSLCertificate::ApplicationVerificationFailed
Definition: ksslcertificate.h:138
QString::number
QString number(int n, int base)
QList::append
void append(const T &value)
QString::insert
QString & insert(int position, QChar ch)
STACK_OF
#define STACK_OF(x)
Definition: ksslpkcs12.h:46
KSSLCertificate::InvalidCA
Definition: ksslcertificate.h:120
KSSLCertChain::setCertChain
void setCertChain(const QStringList &chain)
Set the certificate chain as a list of base64 encoded X.509 certificates.
Definition: ksslcertchain.cpp:184
KSSLCertificate::~KSSLCertificate
~KSSLCertificate()
Destroy this X.509 certificate.
Definition: ksslcertificate.cpp:118
ksslx509v3.h
KSSLCertificate::KSSLValidation
KSSLValidation
Result of the validate() call.
Definition: ksslcertificate.h:119
KSSLCertificate::CertificateRevoked
Definition: ksslcertificate.h:133
KSSLCertificate::KSSLPurpose
KSSLPurpose
Definition: ksslcertificate.h:146
QList::isEmpty
bool isEmpty() const
KSSLCertificate::toString
QString toString()
Convert this certificate to a string.
Definition: ksslcertificate.cpp:1052
QString::isEmpty
bool isEmpty() const
KOSSL
#define KOSSL
Definition: kopenssl.h:25
KSSLCertificate::CRLSignatureFailed
Definition: ksslcertificate.h:135
QByteArray::constData
const char * constData() const
operator<<
QDataStream & operator<<(QDataStream &s, const KSSLCertificate &r)
Definition: ksslcertificate.cpp:1329
KSSLCertificate::CRLFieldLastUpdateErroneous
Definition: ksslcertificate.h:131
QList::first
T & first()
QString
QList
KSSLX509V3
KDE X509v3 Flag Class.
Definition: ksslx509v3.h:37
KSSLCertificate::getKeyType
QString getKeyType() const
Get the key type (RSA, DSA, etc).
Definition: ksslcertificate.cpp:317
KSSLCertificate::getKDEKey
QString getKDEKey() const
KDEKey is a concatenation "Subject (MD5)", mostly needed for SMIME.
Definition: ksslcertificate.cpp:250
KSSLCertificate::NoSSL
Definition: ksslcertificate.h:121
KSSLCertificate::getMD5DigestFromKDEKey
static QString getMD5DigestFromKDEKey(const QString &k)
Aegypten semantics force us to search by MD5Digest only.
Definition: ksslcertificate.cpp:255
KSSLCertificate::isSigner
bool isSigner()
Check if this is a signer certificate.
Definition: ksslcertificate.cpp:1293
QStringList
KSSLCertificate::KSSLCertificate
KSSLCertificate()
Definition: ksslcertificate.cpp:93
KSSLCertificate::isValid
bool isValid()
Check if this is a valid certificate.
Definition: ksslcertificate.cpp:598
QList::end
iterator end()
QString::toLocal8Bit
QByteArray toLocal8Bit() const
KSSLCertificate::fromX509
static KSSLCertificate * fromX509(X509 *x5)
Create an X.509 certificate from the internal representation.
Definition: ksslcertificate.cpp:133
QLatin1Char
ksslutils.h
KSSLCertificate::CertificateSignatureFailed
Definition: ksslcertificate.h:135
KStandardDirs::resourceDirs
QStringList resourceDirs(const char *type) const
KSSLCertificate::DecryptCertificateSignatureFailed
Definition: ksslcertificate.h:136
QTemporaryFile::fileName
QString fileName() const
KSSLCertificate::toText
QString toText()
Convert the certificate to OpenSSL plain text format.
Definition: ksslcertificate.cpp:1250
KSSLCertificate::getNotBefore
QString getNotBefore() const
Get the date that the certificate becomes valid on.
Definition: ksslcertificate.cpp:990
KSSLCertificate::fromString
static KSSLCertificate * fromString(const QByteArray &cert)
Create an X.509 certificate from a base64 encoded string.
Definition: ksslcertificate.cpp:145
KSSLCertificate::AuthAndSubjectKeyIDAndNameMismatched
Definition: ksslcertificate.h:139
KSSLCertificate::CertificateChainTooLong
Definition: ksslcertificate.h:141
KSSLCertificate::Irrelevant
Definition: ksslcertificate.h:124
KSSLCertificate::getNotAfter
QString getNotAfter() const
Get the date that the certificate is valid until.
Definition: ksslcertificate.cpp:999
ktemporaryfile.h
KSSLCertificate::InvalidHost
Definition: ksslcertificate.h:123
QDateTime::currentDateTime
QDateTime currentDateTime()
QString::toLatin1
QByteArray toLatin1() const
QString::mid
QString mid(int position, int n) const
QLatin1String
KSSLCertificate::setChain
void setChain(void *c)
Definition: ksslcertificate.cpp:472
QByteArray::fromBase64
QByteArray fromBase64(const QByteArray &base64)
KSSLCertificate::CertificateFieldNotBeforeErroneous
Definition: ksslcertificate.h:129
kstandarddirs.h
KSSLCertificate::processError
KSSLValidation processError(int ec)
Definition: ksslcertificate.cpp:799
QString::at
const QChar at(int position) const
QList::ConstIterator
typedef ConstIterator
QString::length
int length() const
QByteArray::data
char * data()
KSSLCertificate::SMIMEEncrypt
Definition: ksslcertificate.h:147
KSSLCertificate::subjAltNames
QStringList subjAltNames() const
The alternate subject name.
Definition: ksslcertificate.cpp:1298
KSSLCertificate::toDer
QByteArray toDer()
Convert the certificate to DER (ASN.1) format.
Definition: ksslcertificate.cpp:1160
fopen
FILE * fopen(const QString &pathname, const char *mode)
KSSLCertificate::getSignatureText
QString getSignatureText() const
Get the signature.
Definition: ksslcertificate.cpp:196
KSSLCertificate::GetIssuerCertLocallyFailed
Definition: ksslcertificate.h:126
KSSLCertificate::toPem
QByteArray toPem()
Convert the certificate to PEM (base64) format.
Definition: ksslcertificate.cpp:1182
KSSLCertificate::getMD5Digest
QString getMD5Digest() const
Get the MD5 digest of the certificate.
Definition: ksslcertificate.cpp:294
kcodecs.h
QByteArray::toBase64
QByteArray toBase64() const
kopenssl.h
KSSLCertificate::SelfSignedInChain
Definition: ksslcertificate.h:138
KSSLCertificate::validateVerbose
KSSLValidationList validateVerbose(KSSLPurpose p)
Check if this is a valid certificate.
Definition: ksslcertificate.cpp:642
KSSLCertificate::GetIssuerCertFailed
Definition: ksslcertificate.h:125
KSSLCertificate::SSLClient
Definition: ksslcertificate.h:146
QByteArray::size
int size() const
KSSLCertificate::CRLFieldNextUpdateErroneous
Definition: ksslcertificate.h:132
KSSLCertificate::CertificateRejected
Definition: ksslcertificate.h:137
QTemporaryFile::open
bool open()
ksslcertchain.h
operator==
int operator==(KSSLCertificate &x, KSSLCertificate &y)
Definition: ksslcertificate.cpp:1026
QList::begin
iterator begin()
hv
static char hv[]
Definition: ksslcertificate.cpp:69
KSSLCertificate::setCert
bool setCert(const QString &cert)
Re-set the certificate from a base64 string.
Definition: ksslcertificate.cpp:1273
KSSLCertificate::SelfSignedChain
Definition: ksslcertificate.h:124
QDateTime
KSSLCertificate::getEmails
void getEmails(QStringList &to) const
FIXME: document.
Definition: ksslcertificate.cpp:231
KSSLCertificate::SSLServer
Definition: ksslcertificate.h:146
KSSLCertificate::SMIMESign
Definition: ksslcertificate.h:147
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:24:53 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KIO

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

kdelibs API Reference

Skip menu "kdelibs API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal