XRootD
XrdCryptoFactory.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d C r y p t o F a c t o r y . c c */
4 /* */
5 /* (c) 2004 by the Board of Trustees of the Leland Stanford, Jr., University */
6 /* Produced by Gerri Ganis for CERN */
7 /* */
8 /* This file is part of the XRootD software suite. */
9 /* */
10 /* XRootD is free software: you can redistribute it and/or modify it under */
11 /* the terms of the GNU Lesser General Public License as published by the */
12 /* Free Software Foundation, either version 3 of the License, or (at your */
13 /* option) any later version. */
14 /* */
15 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
16 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
17 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
18 /* License for more details. */
19 /* */
20 /* You should have received a copy of the GNU Lesser General Public License */
21 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
22 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
23 /* */
24 /* The copyright holder's institutional names and contributor's names may not */
25 /* be used to endorse or promote products derived from this software without */
26 /* specific prior written permission of the institution or contributor. */
27 /******************************************************************************/
28 
29 /* ************************************************************************** */
30 /* */
31 /* Abstract interface for a crypto factory */
32 /* Allows to plug-in modules based on different crypto implementation */
33 /* (OpenSSL, Botan, ...) */
34 /* */
35 /* ************************************************************************** */
36 #include <cstring>
37 #include <dlfcn.h>
38 
42 
43 #include "XrdOuc/XrdOucHash.hh"
45 #include "XrdSys/XrdSysPlatform.hh"
46 #include "XrdSys/XrdSysPthread.hh"
47 
48 #include "XrdVersion.hh"
49 
50 //
51 // For error logging
52 static XrdSysError eDest(0,"cryptofactory_");
53 
54 //____________________________________________________________________________
55 XrdCryptoFactory::XrdCryptoFactory(const char *n, int id)
56 {
57  // Constructor (only called by derived classes).
58 
59  if (n) {
60  int l = strlen(n);
61  l = (l > (MAXFACTORYNAMELEN - 1)) ? (MAXFACTORYNAMELEN - 1) : l;
62  memcpy(name,n,l);
63  name[l] = 0; // null terminated
64  }
65  fID = id;
66 }
67 
68 //______________________________________________________________________________
70 {
71  // Set flags for tracing
72 
73  ABSTRACTMETHOD("XrdCryptoFactory::SetTrace");
74 }
75 
76 //______________________________________________________________________________
78 {
79  // Compare name of 'factory' to local name: return 1 if matches, 0 if not
80 
81  if (!strcmp(factory.Name(),Name()))
82  return 1;
83  return 0;
84 }
85 
86 //______________________________________________________________________________
88 {
89  // Return an instance of an implementation of a Key Der function length.
90 
91  ABSTRACTMETHOD("XrdCryptoFactory::KDFunLen");
92  return 0;
93 }
94 
95 //______________________________________________________________________________
97 {
98  // Return an instance of an implementation of a Key Derivation function.
99 
100  ABSTRACTMETHOD("XrdCryptoFactory::KDFun");
101  return 0;
102 }
103 
104 //______________________________________________________________________________
106 {
107  // Returns true id specified cipher is supported by the implementation
108 
109  ABSTRACTMETHOD("XrdCryptoFactory::SupportedCipher");
110  return 0;
111 }
112 
113 //______________________________________________________________________________
115 {
116  // Returns true id specified cipher is supported by the implementation
117 
118  ABSTRACTMETHOD("XrdCryptoFactory::PaddingSupport");
119  return 0;
120 }
121 
122 //______________________________________________________________________________
124 {
125  // Return an instance of an implementation of XrdCryptoCipher.
126 
127  ABSTRACTMETHOD("XrdCryptoFactory::Cipher");
128  return 0;
129 }
130 
131 //______________________________________________________________________________
132 XrdCryptoCipher *XrdCryptoFactory::Cipher(const char *, int, const char *,
133  int, const char *)
134 {
135  // Return an instance of an implementation of XrdCryptoCipher.
136 
137  ABSTRACTMETHOD("XrdCryptoFactory::Cipher");
138  return 0;
139 }
140 
141 //______________________________________________________________________________
143 {
144  // Return an instance of an implementation of XrdCryptoCipher.
145 
146  ABSTRACTMETHOD("XrdCryptoFactory::Cipher");
147  return 0;
148 }
149 
150 //______________________________________________________________________________
151 XrdCryptoCipher *XrdCryptoFactory::Cipher(bool, int, char *, int, const char *)
152 {
153  // Return an instance of an implementation of XrdCryptoCipher.
154 
155  ABSTRACTMETHOD("XrdCryptoFactory::Cipher");
156  return 0;
157 }
158 
159 //______________________________________________________________________________
160 XrdCryptoCipher *XrdCryptoFactory::Cipher(int, char *, int, const char *)
161 {
162  // Return an instance of an implementation of XrdCryptoCipher.
163 
164  ABSTRACTMETHOD("XrdCryptoFactory::Cipher");
165  return 0;
166 }
167 
168 //______________________________________________________________________________
170 {
171  // Return an instance of an implementation of XrdCryptoCipher.
172 
173  ABSTRACTMETHOD("XrdCryptoFactory::Cipher");
174  return 0;
175 }
176 
177 //______________________________________________________________________________
179 {
180  // Returns true id specified digest is supported by the implementation
181 
182  ABSTRACTMETHOD("XrdCryptoFactory::SupportedMsgDigest");
183  return 0;
184 }
185 
186 //______________________________________________________________________________
188 {
189  // Return an instance of an implementation of XrdCryptoMsgDigest.
190 
191  ABSTRACTMETHOD("XrdCryptoFactory::MsgDigest");
192  return 0;
193 }
194 
195 //______________________________________________________________________________
197 {
198  // Return an instance of an implementation of XrdCryptoRSA.
199 
200  ABSTRACTMETHOD("XrdCryptoFactory::RSA");
201  return 0;
202 }
203 
204 //______________________________________________________________________________
206 {
207  // Return an instance of an implementation of XrdCryptoRSA.
208 
209  ABSTRACTMETHOD("XrdCryptoFactory::RSA");
210  return 0;
211 
212 }
213 
214 //______________________________________________________________________________
216 {
217  // Return an instance of an implementation of XrdCryptoRSA.
218 
219  ABSTRACTMETHOD("XrdCryptoFactory::RSA ("<<this<<")");
220  return 0;
221 }
222 
223 //______________________________________________________________________________
224 XrdCryptoX509 *XrdCryptoFactory::X509(const char *, const char *)
225 {
226  // Return an instance of an implementation of XrdCryptoX509.
227 
228  ABSTRACTMETHOD("XrdCryptoFactory::X509");
229  return 0;
230 }
231 
232 //______________________________________________________________________________
234 {
235  // Init XrdCryptoX509 from a bucket
236 
237  ABSTRACTMETHOD("XrdCryptoFactory::X509");
238  return 0;
239 }
240 
241 //______________________________________________________________________________
243 {
244  // Return an instance of an implementation of XrdCryptoX509Crl.
245 
246  ABSTRACTMETHOD("XrdCryptoFactory::X509Crl");
247  return 0;
248 }
249 
250 //______________________________________________________________________________
252 {
253  // Return an instance of an implementation of XrdCryptoX509Crl.
254 
255  ABSTRACTMETHOD("XrdCryptoFactory::X509Crl");
256  return 0;
257 }
258 
259 //______________________________________________________________________________
261 {
262  // Return an instance of an implementation of XrdCryptoX509Req.
263 
264  ABSTRACTMETHOD("XrdCryptoFactory::X509Req");
265  return 0;
266 }
267 
268 //______________________________________________________________________________
270 {
271  // Return an instance of an implementation of a verification
272  // function for X509 certificate.
273 
274  ABSTRACTMETHOD("XrdCryptoFactory::X509VerifyCert");
275  return 0;
276 }
277 
278 //______________________________________________________________________________
280 {
281  // Return an instance of an implementation of a verification
282  // function for X509 certificate chains.
283 
284  ABSTRACTMETHOD("XrdCryptoFactory::X509VerifyChain");
285  return 0;
286 }
287 
288 //______________________________________________________________________________
290 {
291  // Return an instance of an implementation of a function
292  // to export a X509 certificate chain.
293 
294  ABSTRACTMETHOD("XrdCryptoFactory::X509ExportChain");
295  return 0;
296 }
297 
298 //______________________________________________________________________________
300 {
301  // Return an instance of an implementation of a function
302  // to dump a X509 certificate chain to a file.
303 
304  ABSTRACTMETHOD("XrdCryptoFactory::X509ChainToFile");
305  return 0;
306 }
307 
308 //______________________________________________________________________________
310 {
311  // Return an instance of an implementation of a function
312  // to parse a file supposed to contain for X509 certificates.
313 
314  ABSTRACTMETHOD("XrdCryptoFactory::X509ParseFile");
315  return 0;
316 }
317 
318 //______________________________________________________________________________
320 {
321  // Return an instance of an implementation of a function
322  // to parse a stack supposed to contain for X509 certificates.
323 
324  ABSTRACTMETHOD("XrdCryptoFactory::X509ParseStack");
325  return 0;
326 }
327 
328 //______________________________________________________________________________
330 {
331  // Return an instance of an implementation of a function
332  // to parse a bucket supposed to contain for X509 certificates.
333 
334  ABSTRACTMETHOD("XrdCryptoFactory::X509ParseBucket");
335  return 0;
336 }
337 
338 //______________________________________________________________________________
340 {
341  // Check if the proxyCertInfo extension exists
342 
343  ABSTRACTMETHOD("XrdCryptoFactory::ProxyCertInfo");
344  return 0;
345 }
346 
347 //______________________________________________________________________________
349 {
350  // Set the path length constraint
351 
352  ABSTRACTMETHOD("XrdCryptoFactory::SetPathLenConstraint");
353  return 0;
354 }
355 
356 //______________________________________________________________________________
358 {
359  // Create a proxy certificate
360 
361  ABSTRACTMETHOD("XrdCryptoFactory::X509CreateProxy");
362  return 0;
363 }
364 
365 //______________________________________________________________________________
367 {
368  // Create a proxy request
369 
370  ABSTRACTMETHOD("XrdCryptoFactory::X509CreateProxyReq");
371  return 0;
372 }
373 
374 //______________________________________________________________________________
376 {
377  // Sign a proxy request
378 
379  ABSTRACTMETHOD("XrdCryptoFactory::X509SignProxyReq");
380  return 0;
381 }
382 
383 //______________________________________________________________________________
385 {
386  // Check consistency of a GSI 3 compliant proxy
387 
388  ABSTRACTMETHOD("XrdCryptoFactory::X509CheckProxy3");
389  return 0;
390 }
391 
392 //______________________________________________________________________________
394 {
395  // Get VOMS attributes, if any
396 
397  ABSTRACTMETHOD("XrdCryptoFactory::X509GetVOMSAttr");
398  return 0;
399 }
400 
401 
402 /* ************************************************************************** */
403 /* */
404 /* G e t C r y p t o F a c t o r y */
405 /* */
406 /* ************************************************************************** */
407 
408 //
409 // Structure for the local record
410 typedef struct {
412  char factoryname[MAXFACTORYNAMELEN];
413  bool status;
414 } FactoryEntry;
415 
416 //____________________________________________________________________________
418 {
419  // Static method to load/locate the crypto factory named factoryid
420 
421  static XrdVERSIONINFODEF(myVer,cryptoloader,XrdVNUMBER,XrdVERSION);
422  static XrdSysMutex fMutex;
423  static FactoryEntry *factorylist = 0;
424  static int factorynum = 0;
425  static XrdOucHash<XrdOucPinLoader> plugins;
426  XrdCryptoFactory *(*efact)();
427  XrdCryptoFactory *factory;
428  char factobjname[80], libfn[80];
429  EPNAME("Factory::GetCryptoFactory");
430 
431  // Factory entries are tracked in a static list.
432  // Make sure only one thread may be using or modifying the list at a time.
433  XrdSysMutexHelper mHelp(fMutex);
434 
435  //
436  // The id must be defined
437  if (!factoryid) {
438  PRINT("crypto factory ID (NULL) undefined");
439  return 0;
440  }
441  if (!strlen(factoryid)) {
442  PRINT("crypto factory ID (\"\") undefined");
443  return 0;
444  }
445 
446  //
447  // Check if already loaded
448  if (factorynum) {
449  int i = 0;
450  for ( ; i < factorynum; i++ ) {
451  if (!strcmp(factoryid,factorylist[i].factoryname)) {
452  if (factorylist[i].status) {
453  DEBUG(factoryid <<" crypto factory object already loaded ("
454  << factorylist[i].factory << ")");
455  return factorylist[i].factory;
456  } else {
457  DEBUG("previous attempt to load crypto factory "
458  <<factoryid<<" failed - do nothing");
459  return 0;
460  }
461  }
462  }
463  }
464 
465  //
466  // Create new entry for this factory in the local record
467  FactoryEntry *newfactorylist = new FactoryEntry[factorynum+1];
468  if (newfactorylist) {
469  int i = 0;
470  for ( ; i < factorynum; i++ ) {
471  newfactorylist[i].factory = factorylist[i].factory;
472  newfactorylist[i].status = factorylist[i].status;
473  strcpy(newfactorylist[i].factoryname,factorylist[i].factoryname);
474  }
475  newfactorylist[i].factory = 0;
476  newfactorylist[i].status = 0;
477  strcpy(newfactorylist[i].factoryname,factoryid);
478 
479  // Destroy previous vector
480  if (factorylist) delete[] factorylist;
481 
482  // Update local list
483  factorylist = newfactorylist;
484  factorynum++;
485  } else
486  PRINT("cannot create local record of loaded crypto factories");
487 
488  //
489  // Try loading: name of routine to load
490  sprintf(factobjname, "XrdCrypto%sFactoryObject", factoryid);
491 
492  // Create or attach to the plug-in instance
493  XrdOucPinLoader *plug = plugins.Find(factoryid);
494  if (!plug) {
495  // Create one and add it to the list
496  snprintf(libfn, sizeof(libfn)-1, "libXrdCrypto%s.so", factoryid);
497  libfn[sizeof(libfn)-1] = '\0';
498 
499  plug = new XrdOucPinLoader(&myVer, "cryptolib", libfn);
500  plugins.Add(factoryid, plug);
501  }
502  if (!plug) {
503  PRINT("problems opening shared library " << libfn);
504  return 0;
505  }
506  DEBUG("shared library '" << libfn << "' loaded");
507 
508  // Get the function
509  if (!(efact = (XrdCryptoFactory *(*)()) plug->Resolve(factobjname))) {
510  PRINT(plug->LastMsg());
511  PRINT("problems finding crypto factory object creator " << factobjname);
512  return 0;
513  }
514 
515  //
516  // Get the factory object
517  if (!(factory = (*efact)())) {
518  PRINT("problems creating crypto factory object");
519  return 0;
520  }
521 
522  //
523  // Update local record
524  factorylist[factorynum-1].factory = factory;
525  factorylist[factorynum-1].status = 1;
526 
527  return factory;
528 }
int kXR_int32
Definition: XPtypes.hh:89
#define DEBUG(x)
Definition: XrdBwmTrace.hh:54
#define EPNAME(x)
Definition: XrdBwmTrace.hh:56
#define ABSTRACTMETHOD(x)
Definition: XrdCryptoAux.hh:41
int(* XrdCryptoKDFunLen_t)()
Definition: XrdCryptoAux.hh:59
int(* XrdCryptoKDFun_t)(const char *pass, int plen, const char *salt, int slen, char *key, int klen)
Definition: XrdCryptoAux.hh:60
XrdCryptoFactory * factory
static XrdSysError eDest(0,"cryptofactory_")
int(* XrdCryptoX509ChainToFile_t)(XrdCryptoX509Chain *, const char *)
int(* XrdCryptoX509CreateProxy_t)(const char *, const char *, XrdProxyOpt_t *, XrdCryptogsiX509Chain *, XrdCryptoRSA **, const char *)
int(* XrdCryptoX509SignProxyReq_t)(XrdCryptoX509 *, XrdCryptoRSA *, XrdCryptoX509Req *, XrdCryptoX509 **)
bool(* XrdCryptoX509VerifyChain_t)(XrdCryptoX509Chain *chain, int &errcode)
int(* XrdCryptoX509ParseBucket_t)(XrdSutBucket *, XrdCryptoX509Chain *)
bool(* XrdCryptoX509VerifyCert_t)(XrdCryptoX509 *c, XrdCryptoX509 *r)
int(* XrdCryptoX509GetVOMSAttr_t)(XrdCryptoX509 *, XrdOucString &)
void(* XrdCryptoSetPathLenConstraint_t)(void *, int)
int(* XrdCryptoX509ParseStack_t)(XrdTlsPeerCerts *pc, XrdCryptoX509Chain *c)
XrdSutBucket *(* XrdCryptoX509ExportChain_t)(XrdCryptoX509Chain *, bool)
int(* XrdCryptoX509ParseFile_t)(const char *fname, XrdCryptoX509Chain *, const char *)
int(* XrdCryptoX509CreateProxyReq_t)(XrdCryptoX509 *, XrdCryptoX509Req **, XrdCryptoRSA **)
bool(* XrdCryptoProxyCertInfo_t)(const void *, int &, bool *)
int(* XrdCryptoX509CheckProxy3_t)(XrdCryptoX509 *, XrdOucString &)
#define MAXFACTORYNAMELEN
#define PRINT(y)
virtual bool HasPaddingSupport()
virtual XrdCryptoX509VerifyChain_t X509VerifyChain()
virtual XrdCryptoX509ParseBucket_t X509ParseBucket()
virtual XrdCryptoX509CreateProxyReq_t X509CreateProxyReq()
virtual XrdCryptoX509 * X509(const char *cf, const char *kf=0)
virtual void SetTrace(kXR_int32 trace)
virtual XrdCryptoX509ParseFile_t X509ParseFile()
virtual XrdCryptoX509CreateProxy_t X509CreateProxy()
virtual XrdCryptoKDFun_t KDFun()
bool operator==(const XrdCryptoFactory factory)
virtual XrdCryptoX509ParseStack_t X509ParseStack()
virtual XrdCryptoX509GetVOMSAttr_t X509GetVOMSAttr()
virtual XrdCryptoX509ChainToFile_t X509ChainToFile()
char * Name() const
virtual XrdCryptoCipher * Cipher(const char *t, int l=0)
virtual XrdCryptoX509CheckProxy3_t X509CheckProxy3()
virtual XrdCryptoRSA * RSA(int b=0, int e=0)
virtual bool SupportedMsgDigest(const char *dgst)
XrdCryptoFactory(const char *n="Unknown", int id=-1)
virtual XrdCryptoSetPathLenConstraint_t SetPathLenConstraint()
virtual XrdCryptoMsgDigest * MsgDigest(const char *dgst)
virtual XrdCryptoX509Crl * X509Crl(const char *crlfile, int opt=0)
virtual XrdCryptoKDFunLen_t KDFunLen()
virtual XrdCryptoProxyCertInfo_t ProxyCertInfo()
static XrdCryptoFactory * GetCryptoFactory(const char *factoryname)
virtual bool SupportedCipher(const char *t)
virtual XrdCryptoX509Req * X509Req(XrdSutBucket *bck)
virtual XrdCryptoX509SignProxyReq_t X509SignProxyReq()
virtual XrdCryptoX509ExportChain_t X509ExportChain()
virtual XrdCryptoX509VerifyCert_t X509VerifyCert()
T * Add(const char *KeyVal, T *KeyData, const int LifeTime=0, XrdOucHash_Options opt=Hash_default)
Definition: XrdOucHash.icc:61
T * Find(const char *KeyVal, time_t *KeyTime=0)
Definition: XrdOucHash.icc:160
void * Resolve(const char *symbl, int mcnt=1)
const char * LastMsg()
XrdVERSIONINFODEF(myVersion, cmsclient, XrdVNUMBER, XrdVERSION)