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

KIO

  • 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
69static char hv[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
70
71
72class KSSLCertificatePrivate {
73public:
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
93KSSLCertificate::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
103KSSLCertificate::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
118KSSLCertificate::~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
128KSSLCertChain& KSSLCertificate::chain() {
129 return d->_chain;
130}
131
132
133KSSLCertificate *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
145KSSLCertificate *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
167QString 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
182QString 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
196QString 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
231void 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
250QString KSSLCertificate::getKDEKey() const {
251 return getSubject() + " (" + getMD5DigestText() + ')';
252}
253
254
255QString 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
268QString KSSLCertificate::getMD5DigestText() const {
269QString 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
294QString KSSLCertificate::getMD5Digest() const {
295QString 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
317QString KSSLCertificate::getKeyType() const {
318QString 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
345QString KSSLCertificate::getPublicKeyText() const {
346QString rc = "";
347char *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
455QString KSSLCertificate::getIssuer() const {
456QString 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
472void 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
480void 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
580X509 *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
593bool KSSLCertificate::isValid(KSSLCertificate::KSSLPurpose p) {
594 return (validate(p) == KSSLCertificate::Ok);
595}
596
597
598bool KSSLCertificate::isValid() {
599 return isValid(KSSLCertificate::SSLServer);
600}
601
602
603int 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
623KSSLCertificate::KSSLValidation KSSLCertificate::validate() {
624 return validate(KSSLCertificate::SSLServer);
625}
626
627KSSLCertificate::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
642KSSLCertificate::KSSLValidationList KSSLCertificate::validateVerbose(KSSLCertificate::KSSLPurpose purpose)
643{
644 return validateVerbose(purpose, 0);
645}
646
647KSSLCertificate::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
788KSSLCertificate::KSSLValidation KSSLCertificate::revalidate() {
789 return revalidate(KSSLCertificate::SSLServer);
790}
791
792
793KSSLCertificate::KSSLValidation KSSLCertificate::revalidate(KSSLCertificate::KSSLPurpose p) {
794 d->m_stateCached = false;
795 return validate(p);
796}
797
798
799KSSLCertificate::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
990QString 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
999QString 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
1008QDateTime 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
1017QDateTime 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
1026int 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
1038KSSLCertificate *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
1052QString KSSLCertificate::toString()
1053{
1054 return toDer().toBase64();
1055}
1056
1057
1058QString 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
1160QByteArray 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
1182QByteArray KSSLCertificate::toPem() {
1183QByteArray qba;
1184QString thecert = toString();
1185const char *header = "-----BEGIN CERTIFICATE-----\n";
1186const 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
1213typedef 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
1222QByteArray 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
1245return qba;
1246}
1247
1248
1249
1250QString 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
1270return text;
1271}
1272
1273bool 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
1288KSSLX509V3& KSSLCertificate::x509V3Extensions() {
1289 return d->_extensions;
1290}
1291
1292
1293bool KSSLCertificate::isSigner() {
1294 return d->_extensions.certTypeCA();
1295}
1296
1297
1298QStringList 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
1329QDataStream& 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
1344QDataStream& 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
KSSLCertChain
KDE Certificate Chain Representation Class.
Definition: ksslcertchain.h:43
KSSLCertChain::setCertChain
void setCertChain(const QStringList &chain)
Set the certificate chain as a list of base64 encoded X.509 certificates.
Definition: ksslcertchain.cpp:184
KSSLCertChain::rawChain
void * rawChain()
Read the raw chain in OpenSSL format.
Definition: ksslcertchain.cpp:104
KSSLCertificate
KDE X.509 Certificate.
Definition: ksslcertificate.h:75
KSSLCertificate::x509V3Extensions
KSSLX509V3 & x509V3Extensions()
Access the X.509v3 parameters.
Definition: ksslcertificate.cpp:1288
KSSLCertificate::getCert
X509 * getCert()
Definition: ksslcertificate.cpp:580
KSSLCertificate::KSSLCertificate
KSSLCertificate()
Definition: ksslcertificate.cpp:93
KSSLCertificate::KSSLValidation
KSSLValidation
Result of the validate() call.
Definition: ksslcertificate.h:119
KSSLCertificate::Rejected
@ Rejected
Definition: ksslcertificate.h:123
KSSLCertificate::CertificateUntrusted
@ CertificateUntrusted
Definition: ksslcertificate.h:134
KSSLCertificate::Revoked
@ Revoked
Definition: ksslcertificate.h:122
KSSLCertificate::SelfSigned
@ SelfSigned
Definition: ksslcertificate.h:121
KSSLCertificate::KeyMayNotSignCertificate
@ KeyMayNotSignCertificate
Definition: ksslcertificate.h:142
KSSLCertificate::InvalidCA
@ InvalidCA
Definition: ksslcertificate.h:120
KSSLCertificate::CertificateFieldNotAfterErroneous
@ CertificateFieldNotAfterErroneous
Definition: ksslcertificate.h:130
KSSLCertificate::GetIssuerCertFailed
@ GetIssuerCertFailed
Definition: ksslcertificate.h:125
KSSLCertificate::GetCRLFailed
@ GetCRLFailed
Definition: ksslcertificate.h:141
KSSLCertificate::CRLFieldLastUpdateErroneous
@ CRLFieldLastUpdateErroneous
Definition: ksslcertificate.h:131
KSSLCertificate::CertificateRevoked
@ CertificateRevoked
Definition: ksslcertificate.h:133
KSSLCertificate::CRLFieldNextUpdateErroneous
@ CRLFieldNextUpdateErroneous
Definition: ksslcertificate.h:132
KSSLCertificate::CertificateChainTooLong
@ CertificateChainTooLong
Definition: ksslcertificate.h:141
KSSLCertificate::InvalidHost
@ InvalidHost
Definition: ksslcertificate.h:123
KSSLCertificate::CertificateFieldNotBeforeErroneous
@ CertificateFieldNotBeforeErroneous
Definition: ksslcertificate.h:129
KSSLCertificate::CRLHasExpired
@ CRLHasExpired
Definition: ksslcertificate.h:128
KSSLCertificate::SelfSignedChain
@ SelfSignedChain
Definition: ksslcertificate.h:124
KSSLCertificate::DecryptCertificateSignatureFailed
@ DecryptCertificateSignatureFailed
Definition: ksslcertificate.h:136
KSSLCertificate::NoSSL
@ NoSSL
Definition: ksslcertificate.h:121
KSSLCertificate::SignatureFailed
@ SignatureFailed
Definition: ksslcertificate.h:122
KSSLCertificate::CRLNotYetValid
@ CRLNotYetValid
Definition: ksslcertificate.h:128
KSSLCertificate::Ok
@ Ok
Definition: ksslcertificate.h:119
KSSLCertificate::Untrusted
@ Untrusted
Definition: ksslcertificate.h:122
KSSLCertificate::Expired
@ Expired
Definition: ksslcertificate.h:120
KSSLCertificate::GetIssuerCertLocallyFailed
@ GetIssuerCertLocallyFailed
Definition: ksslcertificate.h:126
KSSLCertificate::DecodeIssuerPublicKeyFailed
@ DecodeIssuerPublicKeyFailed
Definition: ksslcertificate.h:125
KSSLCertificate::CertificateSignatureFailed
@ CertificateSignatureFailed
Definition: ksslcertificate.h:135
KSSLCertificate::NoCARoot
@ NoCARoot
Definition: ksslcertificate.h:119
KSSLCertificate::OutOfMemory
@ OutOfMemory
Definition: ksslcertificate.h:140
KSSLCertificate::AuthAndSubjectKeyIDMismatched
@ AuthAndSubjectKeyIDMismatched
Definition: ksslcertificate.h:140
KSSLCertificate::CertificateNotYetValid
@ CertificateNotYetValid
Definition: ksslcertificate.h:127
KSSLCertificate::InvalidPurpose
@ InvalidPurpose
Definition: ksslcertificate.h:119
KSSLCertificate::IssuerSubjectMismatched
@ IssuerSubjectMismatched
Definition: ksslcertificate.h:143
KSSLCertificate::ErrorReadingRoot
@ ErrorReadingRoot
Definition: ksslcertificate.h:121
KSSLCertificate::CRLSignatureFailed
@ CRLSignatureFailed
Definition: ksslcertificate.h:135
KSSLCertificate::DecryptCRLSignatureFailed
@ DecryptCRLSignatureFailed
Definition: ksslcertificate.h:137
KSSLCertificate::AuthAndSubjectKeyIDAndNameMismatched
@ AuthAndSubjectKeyIDAndNameMismatched
Definition: ksslcertificate.h:139
KSSLCertificate::VerifyLeafSignatureFailed
@ VerifyLeafSignatureFailed
Definition: ksslcertificate.h:134
KSSLCertificate::CertificateRejected
@ CertificateRejected
Definition: ksslcertificate.h:137
KSSLCertificate::ApplicationVerificationFailed
@ ApplicationVerificationFailed
Definition: ksslcertificate.h:138
KSSLCertificate::Unknown
@ Unknown
Definition: ksslcertificate.h:119
KSSLCertificate::Irrelevant
@ Irrelevant
Definition: ksslcertificate.h:124
KSSLCertificate::SelfSignedInChain
@ SelfSignedInChain
Definition: ksslcertificate.h:138
KSSLCertificate::CertificateHasExpired
@ CertificateHasExpired
Definition: ksslcertificate.h:127
KSSLCertificate::PathLengthExceeded
@ PathLengthExceeded
Definition: ksslcertificate.h:120
KSSLCertificate::PrivateKeyFailed
@ PrivateKeyFailed
Definition: ksslcertificate.h:123
KSSLCertificate::getSignatureText
QString getSignatureText() const
Get the signature.
Definition: ksslcertificate.cpp:196
KSSLCertificate::revalidate
KSSLValidation revalidate()
Check if this is a valid certificate.
Definition: ksslcertificate.cpp:788
KSSLCertificate::getIssuer
QString getIssuer() const
Get the issuer of the certificate (X.509 map).
Definition: ksslcertificate.cpp:455
KSSLCertificate::isValid
bool isValid()
Check if this is a valid certificate.
Definition: ksslcertificate.cpp:598
KSSLCertificate::getKeyType
QString getKeyType() const
Get the key type (RSA, DSA, etc).
Definition: ksslcertificate.cpp:317
KSSLCertificate::getNotBefore
QString getNotBefore() const
Get the date that the certificate becomes valid on.
Definition: ksslcertificate.cpp:990
KSSLCertificate::getSerialNumber
QString getSerialNumber() const
Get the serial number of the certificate.
Definition: ksslcertificate.cpp:182
KSSLCertificate::setChain
void setChain(void *c)
Definition: ksslcertificate.cpp:472
KSSLCertificate::processError
KSSLValidation processError(int ec)
Definition: ksslcertificate.cpp:799
KSSLCertificate::verifyText
static QString verifyText(KSSLValidation x)
Obtain the localized message that corresponds to a validation result.
Definition: ksslcertificate.cpp:1058
KSSLCertificate::validateVerbose
KSSLValidationList validateVerbose(KSSLPurpose p)
Check if this is a valid certificate.
Definition: ksslcertificate.cpp:642
KSSLCertificate::getSubject
QString getSubject() const
Get the subject of the certificate (X.509 map).
Definition: ksslcertificate.cpp:167
KSSLCertificate::toDer
QByteArray toDer()
Convert the certificate to DER (ASN.1) format.
Definition: ksslcertificate.cpp:1160
KSSLCertificate::getQDTNotAfter
QDateTime getQDTNotAfter() const
Get the date that the certificate is valid until.
Definition: ksslcertificate.cpp:1017
KSSLCertificate::toNetscape
QByteArray toNetscape()
Convert the certificate to Netscape format.
Definition: ksslcertificate.cpp:1222
KSSLCertificate::getPublicKeyText
QString getPublicKeyText() const
Get the public key.
Definition: ksslcertificate.cpp:345
KSSLCertificate::validate
KSSLValidation validate()
Check if this is a valid certificate.
Definition: ksslcertificate.cpp:623
KSSLCertificate::getEmails
void getEmails(QStringList &to) const
FIXME: document.
Definition: ksslcertificate.cpp:231
KSSLCertificate::subjAltNames
QStringList subjAltNames() const
The alternate subject name.
Definition: ksslcertificate.cpp:1298
KSSLCertificate::toString
QString toString()
Convert this certificate to a string.
Definition: ksslcertificate.cpp:1052
KSSLCertificate::KSSLPurpose
KSSLPurpose
Definition: ksslcertificate.h:146
KSSLCertificate::Any
@ Any
Definition: ksslcertificate.h:147
KSSLCertificate::SSLServer
@ SSLServer
Definition: ksslcertificate.h:146
KSSLCertificate::SMIMEEncrypt
@ SMIMEEncrypt
Definition: ksslcertificate.h:147
KSSLCertificate::SMIMESign
@ SMIMESign
Definition: ksslcertificate.h:147
KSSLCertificate::None
@ None
Definition: ksslcertificate.h:146
KSSLCertificate::SSLClient
@ SSLClient
Definition: ksslcertificate.h:146
KSSLCertificate::fromX509
static KSSLCertificate * fromX509(X509 *x5)
Create an X.509 certificate from the internal representation.
Definition: ksslcertificate.cpp:133
KSSLCertificate::~KSSLCertificate
~KSSLCertificate()
Destroy this X.509 certificate.
Definition: ksslcertificate.cpp:118
KSSLCertificate::getNotAfter
QString getNotAfter() const
Get the date that the certificate is valid until.
Definition: ksslcertificate.cpp:999
KSSLCertificate::fromString
static KSSLCertificate * fromString(const QByteArray &cert)
Create an X.509 certificate from a base64 encoded string.
Definition: ksslcertificate.cpp:145
KSSLCertificate::getMD5DigestFromKDEKey
static QString getMD5DigestFromKDEKey(const QString &k)
Aegypten semantics force us to search by MD5Digest only.
Definition: ksslcertificate.cpp:255
KSSLCertificate::getQDTNotBefore
QDateTime getQDTNotBefore() const
Get the date that the certificate becomes valid on.
Definition: ksslcertificate.cpp:1008
KSSLCertificate::toPem
QByteArray toPem()
Convert the certificate to PEM (base64) format.
Definition: ksslcertificate.cpp:1182
KSSLCertificate::getMD5DigestText
QString getMD5DigestText() const
Get the MD5 digest of the certificate.
Definition: ksslcertificate.cpp:268
KSSLCertificate::getMD5Digest
QString getMD5Digest() const
Get the MD5 digest of the certificate.
Definition: ksslcertificate.cpp:294
KSSLCertificate::chain
KSSLCertChain & chain()
Get a reference to the certificate chain.
Definition: ksslcertificate.cpp:128
KSSLCertificate::replicate
KSSLCertificate * replicate()
Explicitly make a copy of this certificate.
Definition: ksslcertificate.cpp:1038
KSSLCertificate::isSigner
bool isSigner()
Check if this is a signer certificate.
Definition: ksslcertificate.cpp:1293
KSSLCertificate::getKDEKey
QString getKDEKey() const
KDEKey is a concatenation "Subject (MD5)", mostly needed for SMIME.
Definition: ksslcertificate.cpp:250
KSSLCertificate::toText
QString toText()
Convert the certificate to OpenSSL plain text format.
Definition: ksslcertificate.cpp:1250
KSSLCertificate::setCert
bool setCert(const QString &cert)
Re-set the certificate from a base64 string.
Definition: ksslcertificate.cpp:1273
KSSLX509V3
KDE X509v3 Flag Class.
Definition: ksslx509v3.h:37
KStandardDirs::addResourceType
bool addResourceType(const char *type, const char *basetype, const char *relativename, bool priority=true)
KStandardDirs::resourceDirs
QStringList resourceDirs(const char *type) const
KTemporaryFile
QList
header
const char header[]
kDebug
#define kDebug
kcodecs.h
kdebug.h
klocale.h
i18n
QString i18n(const char *text)
i18nc
QString i18nc(const char *ctxt, const char *text)
kopenssl.h
KOSSL
#define KOSSL
Definition: kopenssl.h:25
ksslcertchain.h
operator>>
QDataStream & operator>>(QDataStream &s, KSSLCertificate &r)
Definition: ksslcertificate.cpp:1344
NETSCAPE_CERT_HDR
#define NETSCAPE_CERT_HDR
Definition: ksslcertificate.cpp:1208
operator<<
QDataStream & operator<<(QDataStream &s, const KSSLCertificate &r)
Definition: ksslcertificate.cpp:1329
hv
static char hv[]
Definition: ksslcertificate.cpp:69
operator==
int operator==(KSSLCertificate &x, KSSLCertificate &y)
Definition: ksslcertificate.cpp:1026
ksslcertificate.h
kssldefs.h
STACK_OF
#define STACK_OF(x)
Definition: ksslpkcs12.h:46
ksslutils.h
ksslx509v3.h
kstandarddirs.h
ktemporaryfile.h
fopen
FILE * fopen(const QString &pathname, const char *mode)
KGlobal::dirs
KStandardDirs * dirs()
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 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-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 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
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