KDELibs4Support

ksslcertchain.cpp
1 /* This file is part of the KDE project
2  *
3  * Copyright (C) 2001 George Staikos <[email protected]>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this library; see the file COPYING.LIB. If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20 
21 #include "ksslcertchain.h"
22 
23 #include <ksslconfig.h>
24 
25 #include "ksslcertificate.h"
26 
27 // this hack provided by Malte Starostik to avoid glibc/openssl bug
28 // on some systems
29 #if KSSL_HAVE_SSL
30 #define crypt _openssl_crypt
31 #include <openssl/ssl.h>
32 #include <openssl/x509.h>
33 #include <openssl/x509v3.h>
34 #include <openssl/x509_vfy.h>
35 #include <openssl/pem.h>
36 #include <openssl/stack.h>
37 #include <openssl/safestack.h>
38 #undef crypt
39 #endif
40 
41 #include <kopenssl.h>
42 #include <QStringList>
43 
44 class KSSLCertChainPrivate
45 {
46 public:
47  KSSLCertChainPrivate()
48  {
49  kossl = KOSSL::self();
50  }
51 
52  ~KSSLCertChainPrivate()
53  {
54  }
55 
56  KOSSL *kossl;
57 };
58 
60  : d(new KSSLCertChainPrivate)
61 {
62  _chain = nullptr;
63 }
64 
66 {
67 #if KSSL_HAVE_SSL
68  if (_chain) {
69  STACK_OF(X509) *x = (STACK_OF(X509) *)_chain;
70 
71  for (;;) {
72  X509 *x5 = reinterpret_cast<X509*>(d->kossl->OPENSSL_sk_pop(reinterpret_cast<STACK *>(x)));
73  if (!x5) {
74  break;
75  }
76  d->kossl->X509_free(x5);
77  }
78  d->kossl->OPENSSL_sk_free(reinterpret_cast<STACK *>(x));
79  }
80 #endif
81  delete d;
82 }
83 
85 {
86  return (_chain && depth() > 0);
87 }
88 
90 {
93  x->setChain(ch); // this will do a deep copy for us
94  qDeleteAll(ch);
95  return x;
96 }
97 
99 {
100 #if KSSL_HAVE_SSL
101  return d->kossl->OPENSSL_sk_num(static_cast<STACK *>(_chain));
102 #endif
103  return 0;
104 }
105 
107 {
108  return _chain;
109 }
110 
112 {
114  if (!_chain) {
115  return cl;
116  }
117 #if KSSL_HAVE_SSL
118  STACK_OF(X509) *x = (STACK_OF(X509) *)_chain;
119 
120  for (int i = 0; i < d->kossl->OPENSSL_sk_num(reinterpret_cast<STACK *>(x)); i++) {
121  X509 *x5 = reinterpret_cast<X509*>(d->kossl->OPENSSL_sk_value(reinterpret_cast<STACK *>(x), i));
122  if (!x5) {
123  continue;
124  }
126  nc->setCert(d->kossl->X509_dup(x5));
127  cl.append(nc);
128  }
129 
130 #endif
131  return cl;
132 }
133 
135 {
136 #if KSSL_HAVE_SSL
137  if (_chain) {
138  STACK_OF(X509) *x = (STACK_OF(X509) *)_chain;
139 
140  for (;;) {
141  X509 *x5 = reinterpret_cast<X509*>(d->kossl->OPENSSL_sk_pop(reinterpret_cast<STACK*>(x)));
142  if (!x5) {
143  break;
144  }
145  d->kossl->X509_free(x5);
146  }
147  d->kossl->OPENSSL_sk_free(reinterpret_cast<STACK*>(x));
148  _chain = nullptr;
149  }
150 
151  if (chain.isEmpty()) {
152  return;
153  }
154  _chain = (void *)d->kossl->OPENSSL_sk_new(nullptr);
155  foreach (KSSLCertificate *x, chain) {
156  d->kossl->OPENSSL_sk_push(static_cast<STACK*>(_chain), d->kossl->X509_dup(x->getCert()));
157  }
158 
159 #endif
160 }
161 
162 void KSSLCertChain::setChain(void *stack_of_x509)
163 {
164 #if KSSL_HAVE_SSL
165  if (_chain) {
166  STACK_OF(X509) *x = (STACK_OF(X509) *)_chain;
167 
168  for (;;) {
169  X509 *x5 = reinterpret_cast<X509 *>(d->kossl->OPENSSL_sk_pop(reinterpret_cast<STACK *>(x)));
170  if (!x5) {
171  break;
172  }
173  d->kossl->X509_free(x5);
174  }
175  d->kossl->OPENSSL_sk_free(reinterpret_cast<STACK *>(x));
176  _chain = nullptr;
177  }
178 
179  if (!stack_of_x509) {
180  return;
181  }
182 
183  _chain = (void *)d->kossl->OPENSSL_sk_new(nullptr);
184  STACK_OF(X509) *x = (STACK_OF(X509) *)stack_of_x509;
185 
186  for (int i = 0; i < d->kossl->OPENSSL_sk_num(reinterpret_cast<STACK *>(x)); i++) {
187  X509 *x5 = reinterpret_cast<X509*>(d->kossl->OPENSSL_sk_value(reinterpret_cast<STACK *>(x), i));
188  if (!x5) {
189  continue;
190  }
191  d->kossl->OPENSSL_sk_push(reinterpret_cast<STACK *>(_chain), d->kossl->X509_dup(x5));
192  }
193 
194 #else
195  _chain = NULL;
196 #endif
197 }
198 
200 {
202  for (QStringList::ConstIterator s = chain.begin(); s != chain.end(); ++s) {
203  KSSLCertificate *c = KSSLCertificate::fromString((*s).toLocal8Bit());
204  if (c) {
205  cl.append(c);
206  }
207  }
208  setChain(cl);
209 }
KSSLCertChain()
Construct a KSSLCertChain object.
~KSSLCertChain()
Destroy this KSSLCertChain object.
KDE X.509 Certificate.
QList< KSSLCertificate * > getChain() const
Obtain a copy of the certificate chain.
void * rawChain()
Read the raw chain in OpenSSL format.
void setChain(void *stack_of_x509)
Set the raw chain from OpenSSL.
KDE Certificate Chain Representation Class.
Definition: ksslcertchain.h:42
void append(const T &value)
void setCertChain(const QStringList &chain)
Set the certificate chain as a list of base64 encoded X.509 certificates.
bool isEmpty() const const
KSSLCertChain * replicate()
Do a deep copy of the certificate chain.
int depth()
Determine the number of entries (depth) of the chain.
QList::iterator end()
static KSSLCertificate * fromString(const QByteArray &cert)
Create an X.509 certificate from a base64 encoded string.
bool isValid()
Determine if this represents a valid certificate chain.
typedef ConstIterator
QList::iterator begin()
bool setCert(const QString &cert)
Re-set the certificate from a base64 string.
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Tue May 26 2020 22:58:21 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.