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