libdigidocpp
X509CertStore.cpp
Go to the documentation of this file.
1 /*
2  * libdigidocpp
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  *
18  */
19 
20 #include "X509CertStore_p.h"
21 
22 #if defined(_WIN32) && USE_NATIVE_CERTSTORE
23 #include "MSX509CertStore.h"
24 #elif defined(__APPLE__) && USE_NATIVE_CERTSTORE
25 #include "MACX509CertStore.h"
26 #endif
27 #include "DirectoryX509CertStore.h"
28 #include "../../Conf.h"
29 #include "../../log.h"
30 
31 using namespace digidoc;
32 
33 int X509CertStorePrivate::verify_callback(int ok, X509_STORE_CTX *ctx)
34 {
35  switch(X509_STORE_CTX_get_error(ctx))
36  {
37  case X509_V_ERR_CERT_HAS_EXPIRED: return 1;
38  default: return ok;
39  }
40 }
41 
46 
51  : d(new X509CertStorePrivate)
52 {
53  d->stack = sk_X509_new_null();
54  d->store = X509_STORE_new();
55  X509_STORE_set_verify_cb_func(d->store, d->verify_callback);
56 }
57 
62 {
63  X509_STORE_free(d->store);
64  sk_X509_pop_free(d->stack, X509_free);
65  delete d;
66 }
67 
74 {
75  delete INSTANCE;
76  if(!impl)
77  {
78  std::string path = Conf::getInstance()->getCertStorePath();
79  if(path.empty())
80 #if defined(_WIN32) && USE_NATIVE_CERTSTORE
82 #elif defined(__APPLE__) && USE_NATIVE_CERTSTORE
83  INSTANCE = new digidoc::MACX509CertStore();
84 #else
86 #endif
87  else
88  INSTANCE = new digidoc::DirectoryX509CertStore( path );
89  }
90  else
91  INSTANCE = impl;
92 }
93 
98 {
99  delete INSTANCE;
100  INSTANCE = 0;
101 }
102 
107 {
108  if (!INSTANCE)
109  THROW_IOEXCEPTION("X509CertStore is not initialized");
110  return INSTANCE;
111 }
112 
113 
119 STACK_OF(X509)* digidoc::X509CertStore::getCerts() const throw(IOException)
120 {
121  return d->stack;
122 }
123 
130 {
131  return d->store;
132 }
133 
143 X509* digidoc::X509CertStore::getCert(const X509_NAME *subject) const throw(IOException)
144 {
145  for(int i = 0; i < sk_X509_num(d->stack); ++i)
146  {
147  X509 *x = sk_X509_value(d->stack, i);
148  if(X509_NAME_cmp(X509_get_subject_name(x), subject) == 0)
149  return X509Cert::copyX509(x);
150  }
151  return 0;
152 }
153 
163 STACK_OF(X509)* digidoc::X509CertStore::findCerts(const std::string &obj, const std::string &name) const throw(IOException)
164 {
165  STACK_OF(X509) *result = sk_X509_new_null();
166  if(!result)
167  THROW_IOEXCEPTION("Failed to create X.509 certificate stack.");
168 
169  for(int i = 0; i < sk_X509_num(d->stack); ++i)
170  {
171  X509Cert cert(sk_X509_value(d->stack, i));
172  if(cert.isValid() && cert.getSubjectName(obj) == name)
173  sk_X509_push(result, cert.getX509());
174  }
175 
176  return result;
177 }