XRootD
XrdCryptosslAux.hh File Reference
#include "XrdCrypto/XrdCryptoAux.hh"
#include "XrdCrypto/XrdCryptoFactory.hh"
#include "XrdCrypto/XrdCryptoX509Chain.hh"
#include <openssl/asn1.h>
+ Include dependency graph for XrdCryptosslAux.hh:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define kErrPX_BadEECfile   2
 
#define kErrPX_BadEECkey   3
 
#define kErrPX_BadExtension   13
 
#define kErrPX_BadNames   11
 
#define kErrPX_BadSerial   12
 
#define kErrPX_Error   1
 
#define kErrPX_ExpiredEEC   4
 
#define kErrPX_GenerateKey   9
 
#define kErrPX_NoResources   5
 
#define kErrPX_ProxyFile   10
 
#define kErrPX_SetAttribute   6
 
#define kErrPX_SetPathDepth   7
 
#define kErrPX_Signing   8
 
#define kSslKDFunDefLen   24
 
#define sslTRACE_ALL   0x0007
 
#define sslTRACE_Debug   0x0002
 
#define sslTRACE_Dump   0x0004
 
#define sslTRACE_Notify   0x0001
 

Functions

time_t XrdCryptosslASN1toUTC (const ASN1_TIME *tsn1)
 
int XrdCryptosslKDFun (const char *pass, int plen, const char *salt, int slen, char *key, int len)
 
int XrdCryptosslKDFunLen ()
 
void XrdCryptosslNameOneLine (X509_NAME *nm, XrdOucString &s)
 
bool XrdCryptosslProxyCertInfo (const void *ext, int &pathlen, bool *haspolicy=0)
 
void XrdCryptosslSetPathLenConstraint (void *ext, int pathlen)
 
int XrdCryptosslX509ChainToFile (XrdCryptoX509Chain *c, const char *fn)
 
int XrdCryptosslX509CheckProxy3 (XrdCryptoX509 *, XrdOucString &)
 
int XrdCryptosslX509CreateProxy (const char *, const char *, XrdProxyOpt_t *, XrdCryptogsiX509Chain *, XrdCryptoRSA **, const char *)
 
int XrdCryptosslX509CreateProxyReq (XrdCryptoX509 *, XrdCryptoX509Req **, XrdCryptoRSA **)
 
XrdSutBucketXrdCryptosslX509ExportChain (XrdCryptoX509Chain *c, bool key=0)
 
int XrdCryptosslX509GetVOMSAttr (XrdCryptoX509 *, XrdOucString &)
 
int XrdCryptosslX509ParseBucket (XrdSutBucket *b, XrdCryptoX509Chain *c)
 
int XrdCryptosslX509ParseFile (const char *fname, XrdCryptoX509Chain *c, const char *fkey=0)
 
int XrdCryptosslX509ParseFile (FILE *file, XrdCryptoX509Chain *c, const char *fname, const char *fkey=0)
 
int XrdCryptosslX509ParseStack (XrdTlsPeerCerts *pc, XrdCryptoX509Chain *chain)
 
int XrdCryptosslX509SignProxyReq (XrdCryptoX509 *, XrdCryptoRSA *, XrdCryptoX509Req *, XrdCryptoX509 **)
 
int XrdCryptosslX509ToFile (XrdCryptoX509 *x509, FILE *file, const char *fname)
 
bool XrdCryptosslX509VerifyCert (XrdCryptoX509 *c, XrdCryptoX509 *r)
 
bool XrdCryptosslX509VerifyChain (XrdCryptoX509Chain *chain, int &errcode)
 

Macro Definition Documentation

◆ kErrPX_BadEECfile

#define kErrPX_BadEECfile   2

Definition at line 112 of file XrdCryptosslAux.hh.

◆ kErrPX_BadEECkey

#define kErrPX_BadEECkey   3

Definition at line 113 of file XrdCryptosslAux.hh.

◆ kErrPX_BadExtension

#define kErrPX_BadExtension   13

Definition at line 123 of file XrdCryptosslAux.hh.

◆ kErrPX_BadNames

#define kErrPX_BadNames   11

Definition at line 121 of file XrdCryptosslAux.hh.

◆ kErrPX_BadSerial

#define kErrPX_BadSerial   12

Definition at line 122 of file XrdCryptosslAux.hh.

◆ kErrPX_Error

#define kErrPX_Error   1

Definition at line 111 of file XrdCryptosslAux.hh.

◆ kErrPX_ExpiredEEC

#define kErrPX_ExpiredEEC   4

Definition at line 114 of file XrdCryptosslAux.hh.

◆ kErrPX_GenerateKey

#define kErrPX_GenerateKey   9

Definition at line 119 of file XrdCryptosslAux.hh.

◆ kErrPX_NoResources

#define kErrPX_NoResources   5

Definition at line 115 of file XrdCryptosslAux.hh.

◆ kErrPX_ProxyFile

#define kErrPX_ProxyFile   10

Definition at line 120 of file XrdCryptosslAux.hh.

◆ kErrPX_SetAttribute

#define kErrPX_SetAttribute   6

Definition at line 116 of file XrdCryptosslAux.hh.

◆ kErrPX_SetPathDepth

#define kErrPX_SetPathDepth   7

Definition at line 117 of file XrdCryptosslAux.hh.

◆ kErrPX_Signing

#define kErrPX_Signing   8

Definition at line 118 of file XrdCryptosslAux.hh.

◆ kSslKDFunDefLen

#define kSslKDFunDefLen   24

Definition at line 42 of file XrdCryptosslAux.hh.

◆ sslTRACE_ALL

#define sslTRACE_ALL   0x0007

Definition at line 103 of file XrdCryptosslAux.hh.

◆ sslTRACE_Debug

#define sslTRACE_Debug   0x0002

Definition at line 105 of file XrdCryptosslAux.hh.

◆ sslTRACE_Dump

#define sslTRACE_Dump   0x0004

Definition at line 104 of file XrdCryptosslAux.hh.

◆ sslTRACE_Notify

#define sslTRACE_Notify   0x0001

Definition at line 106 of file XrdCryptosslAux.hh.

Function Documentation

◆ XrdCryptosslASN1toUTC()

time_t XrdCryptosslASN1toUTC ( const ASN1_TIME *  tsn1)

Definition at line 675 of file XrdCryptosslAux.cc.

676 {
677  // Function to convert from ASN1 time format into UTC
678  // since Epoch (Jan 1, 1970)
679  // Return -1 if something went wrong
680  time_t etime = -1;
681 // EPNAME("ASN1toUTC");
682 
683  //
684  // Make sure there is something to convert
685  if (!tsn1) return etime;
686 
687  //
688  // Parse the input string: here we basically cut&paste from GRIDSITE
689  // They finally use timegm to convert to UTC seconds, which is less
690  // standard and seems to give an offset of 3600 secs.
691  // Our result is in agreement with 'date +%s`.
692  struct tm ltm;
693  char zz;
694  if ((sscanf((const char *)(tsn1->data),
695  "%02d%02d%02d%02d%02d%02d%c",
696  &(ltm.tm_year), &(ltm.tm_mon), &(ltm.tm_mday),
697  &(ltm.tm_hour), &(ltm.tm_min), &(ltm.tm_sec),
698  &zz) != 7) || (zz != 'Z')) {
699  // Try GeneralizedTime
700  if ((sscanf((const char *)(tsn1->data),
701  "%04d%02d%02d%02d%02d%02d%c",
702  &(ltm.tm_year), &(ltm.tm_mon), &(ltm.tm_mday),
703  &(ltm.tm_hour), &(ltm.tm_min), &(ltm.tm_sec),
704  &zz) != 7) || (zz != 'Z')) {
705  return -1;
706  }
707  }
708  // Init also the ones not used by mktime
709  ltm.tm_wday = 0; // day of the week
710  ltm.tm_yday = 0; // day in the year
711  ltm.tm_isdst = 0; // we will correct with an offset without dst
712  //
713  // Renormalize some values (year should be modulo 1900), honouring all cases
714  if (ltm.tm_year < 50) {
715  ltm.tm_year += 2000;
716  } else if (ltm.tm_year < 100) {
717  ltm.tm_year += 1900;
718  }
719  ltm.tm_year -= 1900;
720  //
721  // month should in [0, 11]
722  (ltm.tm_mon)--;
723  //
724  // Calculate as if the UTC stamp was a localtime with no dst
725  etime = mktime(&ltm);
726  // Correct to UTC
727  etime += XrdCryptoTZCorr();
728  // Notify, if requested
729 // DEBUG(" UTC: "<<etime<<" isdst: "<<ltm.tm_isdst);
730  //
731  // We are done
732  return etime;
733 }
time_t XrdCryptoTZCorr()
Definition: XrdCryptoAux.cc:77

References XrdCryptoTZCorr().

Referenced by XrdCryptosslX509Crl::LastUpdate(), XrdCryptosslX509Crl::NextUpdate(), XrdCryptosslX509::NotAfter(), and XrdCryptosslX509::NotBefore().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ XrdCryptosslKDFun()

int XrdCryptosslKDFun ( const char *  pass,
int  plen,
const char *  salt,
int  slen,
char *  key,
int  len 
)

Definition at line 78 of file XrdCryptosslAux.cc.

80 {
81  // Password-Based Key Derivation Function 2, specified in PKCS #5
82  // Following (J.Viega, M.Messier, "Secure programming Cookbook", p.141),
83  // the default number of iterations is set to 10000 .
84  // It can be specified at the beginning of the salt using a construct
85  // like this: salt = "$$<number_of_iterations>$<effective_salt>"
86 
87  klen = (klen <= 0) ? 24 : klen;
88 
89  // Defaults
90  char *realsalt = (char *)salt;
91  int realslen = slen;
92  int it = 10000;
93  //
94  // Extract iteration number from salt, if any
95  char *ibeg = (char *)memchr(salt+1,'$',slen-1);
96  if (ibeg) {
97  char *del = 0;
98  int newit = strtol(ibeg+1, &del, 10);
99  if (newit > 0 && del[0] == '$' && errno != ERANGE) {
100  // found iteration number
101  it = newit;
102  realsalt = del+1;
103  realslen = slen - (int)(realsalt-salt);
104  }
105  }
106 
107  PKCS5_PBKDF2_HMAC_SHA1(pass, plen,
108  (unsigned char *)realsalt, realslen, it,
109  klen, (unsigned char *)key);
110  return klen;
111 }

Referenced by XrdCryptosslFactory::KDFun().

+ Here is the caller graph for this function:

◆ XrdCryptosslKDFunLen()

int XrdCryptosslKDFunLen ( )

Definition at line 71 of file XrdCryptosslAux.cc.

72 {
73  // default buffer length
74  return kSslKDFunDefLen;
75 }
#define kSslKDFunDefLen

References kSslKDFunDefLen.

Referenced by XrdCryptosslFactory::KDFunLen().

+ Here is the caller graph for this function:

◆ XrdCryptosslNameOneLine()

void XrdCryptosslNameOneLine ( X509_NAME *  nm,
XrdOucString s 
)

Definition at line 736 of file XrdCryptosslAux.cc.

737 {
738  // Function to convert X509_NAME into a one-line human readable string
739 
740 #ifndef USEX509NAMEONELINE
741  BIO *mbio = BIO_new(BIO_s_mem());
742  X509_NAME_print_ex(mbio, nm, 0, XN_FLAG_SEP_MULTILINE);
743  char *data = 0;
744  long len = BIO_get_mem_data(mbio, &data);
745  s = "/";
746  s.insert(data, 1, len);
747  BIO_free(mbio);
748  s.replace("\n", "/");
749 #else
750  char *xn = X509_NAME_oneline(nm, 0, 0);
751  s = xn;
752  OPENSSL_free(xn);
753 #endif
754 
755  // Done
756  return;
757 }
void insert(const int i, int start=-1)
int replace(const char *s1, const char *s2, int from=0, int to=-1)

References XrdOucString::insert(), and XrdOucString::replace().

Referenced by XrdCryptosslX509::Issuer(), XrdCryptosslX509Crl::Issuer(), XrdCryptosslX509::Subject(), and XrdCryptosslX509Req::Subject().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ XrdCryptosslProxyCertInfo()

bool XrdCryptosslProxyCertInfo ( const void *  ext,
int &  pathlen,
bool *  haspolicy = 0 
)

Referenced by XrdCryptosslFactory::ProxyCertInfo().

+ Here is the caller graph for this function:

◆ XrdCryptosslSetPathLenConstraint()

void XrdCryptosslSetPathLenConstraint ( void *  ext,
int  pathlen 
)

Referenced by XrdCryptosslFactory::SetPathLenConstraint().

+ Here is the caller graph for this function:

◆ XrdCryptosslX509ChainToFile()

int XrdCryptosslX509ChainToFile ( XrdCryptoX509Chain c,
const char *  fn 
)

Definition at line 307 of file XrdCryptosslAux.cc.

308 {
309  // Dump non-CA content of chain 'c' into file 'fn'
310  EPNAME("X509ChainToFile");
311 
312  // Check inputs
313  if (!ch || !fn) {
314  DEBUG("Invalid inputs");
315  return -1;
316  }
317 
318  // We proceed only if we can lock for write
319  FILE *fp = fopen(fn,"w");
320  if (!fp) {
321  DEBUG("cannot open file to save chain (file: "<<fn<<")");
322  return -1;
323  }
324  int ifp = fileno(fp);
325  if (ifp == -1) {
326  DEBUG("got invalid file descriptor (file: "<<fn<<")");
327  fclose(fp);
328  return -1;
329  }
330 
331  // We need to lock from now on
333 
334  // If not successful, return
335  if (!fl.IsValid()) {
336  DEBUG("could not lock file: "<<fn<<")");
337  fclose(fp);
338  return -1;
339  }
340 
341  // Set permissions to 0600
342  if (fchmod(ifp, 0600) == -1) {
343  DEBUG("cannot set permissions on file: "<<fn<<" (errno: "<<errno<<")");
344  fclose(fp);
345  return -1;
346  }
347 
348  // Reorder the chain
349  ch->Reorder();
350 
351  // Write the last cert first
352  XrdCryptoX509 *c = ch->End();
353  if (PEM_write_X509(fp, (X509 *)c->Opaque()) != 1) {
354  DEBUG("error while writing proxy certificate");
355  fclose(fp);
356  return -1;
357  }
358  // Write its private key, if any
359  XrdCryptoRSA *k = c->PKI();
360  if (k->status == XrdCryptoRSA::kComplete) {
361  if (PEM_write_PrivateKey(fp, (EVP_PKEY *)(k->Opaque()),
362  0, 0, 0, 0, 0) != 1) {
363  DEBUG("error while writing proxy private key");
364  fclose(fp);
365  return -1;
366  }
367  }
368  // Now write all other certificates
369  while ((c = ch->SearchBySubject(c->Issuer())) && c->type != XrdCryptoX509::kCA) {
370  // Write to file
371  if (PEM_write_X509(fp, (X509 *)c->Opaque()) != 1) {
372  DEBUG("error while writing proxy certificate");
373  fclose(fp);
374  return -1;
375  }
376  }
377  } // Unlocks the file
378 
379  // CLose the file
380  fclose(fp);
381  //
382  // We are done
383  return 0;
384 }
#define DEBUG(x)
Definition: XrdBwmTrace.hh:54
#define EPNAME(x)
Definition: XrdBwmTrace.hh:56
int fclose(FILE *stream)
#define fopen(a, b)
Definition: XrdPosix.hh:54
ERSAStatus status
Definition: XrdCryptoRSA.hh:58
virtual XrdCryptoRSAdata Opaque()
Definition: XrdCryptoRSA.cc:51
XrdCryptoX509 * End() const
virtual XrdCryptoX509data Opaque()
virtual XrdCryptoRSA * PKI()
virtual const char * Issuer()
EX509Type type

References DEBUG, XrdCryptoX509Chain::End(), EPNAME, fclose(), fopen, XrdCryptoX509::Issuer(), XrdSutFileLocker::IsValid(), XrdCryptoX509::kCA, XrdCryptoRSA::kComplete, XrdSutFileLocker::kExcl, XrdCryptoRSA::Opaque(), XrdCryptoX509::Opaque(), XrdCryptoX509::PKI(), XrdCryptoX509Chain::Reorder(), XrdCryptoX509Chain::SearchBySubject(), XrdCryptoRSA::status, and XrdCryptoX509::type.

Referenced by XrdCryptosslFactory::X509ChainToFile().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ XrdCryptosslX509CheckProxy3()

int XrdCryptosslX509CheckProxy3 ( XrdCryptoX509 ,
XrdOucString  
)

Referenced by XrdCryptosslFactory::X509CheckProxy3().

+ Here is the caller graph for this function:

◆ XrdCryptosslX509CreateProxy()

int XrdCryptosslX509CreateProxy ( const char *  ,
const char *  ,
XrdProxyOpt_t ,
XrdCryptogsiX509Chain ,
XrdCryptoRSA **  ,
const char *   
)

Referenced by XrdCryptosslFactory::X509CreateProxy().

+ Here is the caller graph for this function:

◆ XrdCryptosslX509CreateProxyReq()

int XrdCryptosslX509CreateProxyReq ( XrdCryptoX509 ,
XrdCryptoX509Req **  ,
XrdCryptoRSA **   
)

Referenced by XrdCryptosslFactory::X509CreateProxyReq().

+ Here is the caller graph for this function:

◆ XrdCryptosslX509ExportChain()

XrdSutBucket* XrdCryptosslX509ExportChain ( XrdCryptoX509Chain c,
bool  key = 0 
)

Definition at line 194 of file XrdCryptosslAux.cc.

196 {
197  // Export non-CA content of 'chain' into a bucket for transfer.
198  EPNAME("X509ExportChain");
199  XrdSutBucket *bck = 0;
200 
201  // Make sure we got something to export
202  if (!chain || chain->Size() <= 0) {
203  DEBUG("chain undefined or empty: nothing to export");
204  return bck;
205  }
206 
207  // Do not export CA selfsigned certificates
208  if (chain->Size() == 1 && chain->Begin()->type == XrdCryptoX509::kCA &&
209  !strcmp(chain->Begin()->IssuerHash(),chain->Begin()->SubjectHash())) {
210  DEBUG("chain contains only a CA certificate: nothing to export");
211  return bck;
212  }
213 
214  // Now we create a bio_mem to serialize the certificates
215  BIO *bmem = BIO_new(BIO_s_mem());
216  if (!bmem) {
217  DEBUG("unable to create BIO for memory operations");
218  return bck;
219  }
220 
221  // Reorder the chain
222  chain->Reorder();
223 
224  // Write the last cert first
225  XrdCryptoX509 *c = chain->End();
226  if (!PEM_write_bio_X509(bmem, (X509 *)c->Opaque())) {
227  DEBUG("error while writing proxy certificate");
228  BIO_free(bmem);
229  return bck;
230  }
231  // Write its private key, if any and if asked
232  if (withprivatekey) {
233  XrdCryptoRSA *k = c->PKI();
234  if (k->status == XrdCryptoRSA::kComplete) {
235  if (!PEM_write_bio_PrivateKey(bmem, (EVP_PKEY *)(k->Opaque()),
236  0, 0, 0, 0, 0)) {
237  DEBUG("error while writing proxy private key");
238  BIO_free(bmem);
239  return bck;
240  }
241  }
242  }
243  // Now write all other certificates (except selfsigned CAs ...)
244  while ((c = chain->SearchBySubject(c->Issuer()))) {
245  if (c->type == XrdCryptoX509::kCA) {
246  DEBUG("Encountered CA in chain; breaking. Subject: " << c->Subject());
247  break;
248  }
249  if (strcmp(c->IssuerHash(), c->SubjectHash())) {
250  // Write to bucket
251  if (!PEM_write_bio_X509(bmem, (X509 *)c->Opaque())) {
252  DEBUG("error while writing proxy certificate");
253  BIO_free(bmem);
254  return bck;
255  }
256  } else {
257  DEBUG("Encountered self-signed CA in chain; breaking. Subject: " << c->Subject());
258  break;
259  }
260  }
261 
262  // Extract pointer to BIO data and length of segment
263  char *bdata = 0;
264  int blen = BIO_get_mem_data(bmem, &bdata);
265  DEBUG("BIO data: "<<blen<<" bytes at 0x"<<(int *)bdata);
266 
267  // create the bucket now
268  bck = new XrdSutBucket(0, 0, kXRS_x509);
269  if (bck) {
270  // Fill bucket
271  bck->SetBuf(bdata, blen);
272  DEBUG("result of serialization: "<<bck->size<<" bytes");
273  } else {
274  DEBUG("unable to create bucket for serialized format");
275  BIO_free(bmem);
276  return bck;
277  }
278  //
279  // Free BIO
280  BIO_free(bmem);
281  //
282  // We are done
283  return bck;
284 }
@ kXRS_x509
Definition: XrdSutAux.hh:79
virtual const char * Subject()
virtual const char * SubjectHash(int)
virtual const char * IssuerHash(int)
kXR_int32 size
Definition: XrdSutBucket.hh:47
int SetBuf(const char *nb=0, int ns=0)

References XrdCryptoX509Chain::Begin(), DEBUG, XrdCryptoX509Chain::End(), EPNAME, XrdCryptoX509::Issuer(), XrdCryptoX509::IssuerHash(), XrdCryptoX509::kCA, XrdCryptoRSA::kComplete, kXRS_x509, XrdCryptoRSA::Opaque(), XrdCryptoX509::Opaque(), XrdCryptoX509::PKI(), XrdCryptoX509Chain::Reorder(), XrdCryptoX509Chain::SearchBySubject(), XrdSutBucket::SetBuf(), XrdCryptoX509Chain::Size(), XrdSutBucket::size, XrdCryptoRSA::status, XrdCryptoX509::Subject(), XrdCryptoX509::SubjectHash(), and XrdCryptoX509::type.

Referenced by XrdCryptosslFactory::X509ExportChain().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ XrdCryptosslX509GetVOMSAttr()

int XrdCryptosslX509GetVOMSAttr ( XrdCryptoX509 ,
XrdOucString  
)

Referenced by XrdCryptosslFactory::X509GetVOMSAttr().

+ Here is the caller graph for this function:

◆ XrdCryptosslX509ParseBucket()

int XrdCryptosslX509ParseBucket ( XrdSutBucket b,
XrdCryptoX509Chain c 
)

Definition at line 567 of file XrdCryptosslAux.cc.

568 {
569  // Import certificate(s) from bucket b adding them to 'chain'
570  // (which must be initialized by the caller).
571  EPNAME("X509ParseBucket");
572  int nci = 0;
573 
574  // Make sure we got something to import
575  if (!b || b->size <= 0) {
576  DEBUG("bucket undefined or empty: can do nothing");
577  return nci;
578  }
579 
580  // Make sure we got a chain where to add the certificates
581  if (!chain) {
582  DEBUG("chain undefined: can do nothing");
583  return nci;
584  }
585  //
586  // Now we create a bio_mem to store the certificates
587  BIO *bmem = BIO_new(BIO_s_mem());
588  if (!bmem) {
589  DEBUG("unable to create BIO to import certificates");
590  return nci;
591  }
592 
593  // Write data to BIO
594  if (BIO_write(bmem,(const void *)(b->buffer),b->size) != b->size) {
595  DEBUG("problems writing data to BIO");
596  BIO_free(bmem);
597  return nci;
598  }
599 
600  // Get certificates from BIO
601  X509 *xcer = 0;
602  while (PEM_read_bio_X509(bmem, &xcer, 0, 0)) {
603  //
604  // Create container and add to the list
605  XrdCryptoX509 *c = new XrdCryptosslX509(xcer);
606  if (c) {
607  chain->PushBack(c);
608  nci++;
609  DEBUG("certificate added to the chain - ord: "<<chain->Size());
610  } else {
611  DEBUG("could not create certificate: memory exhausted?");
612  BIO_free(bmem);
613  return nci;
614  }
615  // reset cert otherwise the next one is not fetched
616  xcer = 0;
617  }
618 
619  // If we found something, and we are asked to extract a key,
620  // refill the BIO and search again for the key (this is mandatory
621  // as read operations modify the BIO contents; a read-only BIO
622  // may be more efficient)
623  if (nci && BIO_write(bmem,(const void *)(b->buffer),b->size) == b->size) {
624  EVP_PKEY *rsa = 0;
625  if (!PEM_read_bio_PrivateKey(bmem, &rsa, 0, 0)) {
626  DEBUG("no RSA private key found in bucket");
627  } else {
628  DEBUG("found a RSA private key in bucket");
629  // We need to complete the key
630  // check all the public keys of the loaded certificates
631  if (rsa) {
632  // Loop over the chain certificates
633  XrdCryptoX509 *cert = chain->Begin();
634  while (cert && cert->Opaque()) {
635  if (cert->type != XrdCryptoX509::kCA) {
636  // Get the public key
637  EVP_PKEY *evpp = X509_get_pubkey((X509 *)(cert->Opaque()));
638  if (evpp) {
639  // Test consistency
640 #if OPENSSL_VERSION_NUMBER < 0x30000000L
641  int rc = EVP_PKEY_cmp(evpp, rsa);
642 #else
643  int rc = EVP_PKEY_eq(evpp, rsa);
644 #endif
645  EVP_PKEY_free(evpp);
646  if (rc == 1) {
647  // Update PKI in certificate; also tests if the key is complete
648  cert->SetPKI((XrdCryptoX509data)rsa);
649  if (cert->PKI()->status == XrdCryptoRSA::kComplete) {
650  DEBUG("RSA key completed");
651  break;
652  }
653  }
654  }
655  }
656  // Get next
657  cert = chain->Next();
658  }
659  if (!cert)
660  EVP_PKEY_free(rsa);
661  }
662  else
663  EVP_PKEY_free(rsa);
664  }
665  }
666 
667  // Cleanup
668  BIO_free(bmem);
669 
670  // We are done
671  return nci;
672 }
void * XrdCryptoX509data
virtual void SetPKI(XrdCryptoX509data pki)

References XrdCryptoX509Chain::Begin(), XrdSutBucket::buffer, DEBUG, EPNAME, XrdCryptoX509::kCA, XrdCryptoRSA::kComplete, XrdCryptoX509Chain::Next(), XrdCryptoX509::Opaque(), XrdCryptoX509::PKI(), XrdCryptoX509Chain::PushBack(), XrdCryptoX509::SetPKI(), XrdCryptoX509Chain::Size(), XrdSutBucket::size, XrdCryptoRSA::status, and XrdCryptoX509::type.

Referenced by XrdCryptosslFactory::X509ParseBucket(), and XrdSecgsiAuthzKey().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ XrdCryptosslX509ParseFile() [1/2]

int XrdCryptosslX509ParseFile ( const char *  fname,
XrdCryptoX509Chain c,
const char *  fkey = 0 
)

Definition at line 436 of file XrdCryptosslAux.cc.

438 {
439  EPNAME("X509ParseFile");
440 
441  //
442  // Open file and read the content:
443  // it should contain blocks on information in PEM form
444  FILE *fcer = fopen(fname, "r");
445  if (!fcer) {
446  DEBUG("unable to open file (errno: "<<errno<<")");
447  return 0;
448  }
449 
450  auto retval = XrdCryptosslX509ParseFile(fcer, chain, fname, fkey);
451  fclose(fcer);
452  return retval;
453 }
int XrdCryptosslX509ParseFile(const char *fname, XrdCryptoX509Chain *chain, const char *fkey)

References DEBUG, EPNAME, fclose(), and fopen.

Referenced by XrdCryptosslFactory::X509ParseFile().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ XrdCryptosslX509ParseFile() [2/2]

int XrdCryptosslX509ParseFile ( FILE *  file,
XrdCryptoX509Chain c,
const char *  fname,
const char *  fkey = 0 
)

Definition at line 456 of file XrdCryptosslAux.cc.

459 {
460  // Parse content of file 'fname' and add X509 certificates to
461  // chain (which must be initialized by the caller).
462  // If a private key matching the public key of one of the certificates
463  // is found in the file, the certificate key is completed.
464  EPNAME("X509ParseFile");
465  int nci = 0;
466 
467  // Make sure we got a valid file
468  if (!fcer) {
469  DEBUG("FILE object undefined: can do nothing");
470  return nci;
471  }
472 
473  // Make sure we got a chain where to add the certificates
474  if (!chain) {
475  DEBUG("chain undefined: can do nothing");
476  return nci;
477  }
478 
479  // Now read out certificates and add them to the chain
480  X509 *xcer = 0;
481  while (PEM_read_X509(fcer, &xcer, 0, 0)) {
482  // Add it to the chain
483  XrdCryptoX509 *c = new XrdCryptosslX509(xcer);
484  if (c) {
485  chain->PushBack(c);
486  nci++;
487  DEBUG("certificate for '"<<c->Subject()<<"'added to the chain - ord: "<<chain->Size());
488  } else {
489  DEBUG("could not create certificate: memory exhausted?");
490  fclose(fcer);
491  return nci;
492  }
493  xcer = 0;
494  }
495 
496  // If we found something, and we are asked to extract a key,
497  // rewind and look for it
498  if (nci) {
499  FILE *fcersave = 0;
500  if (!fkey) {
501  // Look in the same file, after rewinding
502  rewind(fcer);
503  } else {
504  // We can close the file now
505  fcersave = fcer;
506  // Open key file
507  fcer = fopen(fkey, "r");
508  if (!fcer) {
509  DEBUG("unable to open key file (errno: "<<errno<<")");
510  fcer = fcersave;
511  return nci;
512  }
513  }
514  EVP_PKEY *rsa = 0;
515  if (!PEM_read_PrivateKey(fcer, &rsa, 0, 0)) {
516  DEBUG("no RSA private key found in file " << fname);
517  } else {
518  DEBUG("found a RSA private key in file " << fname);
519  // We need to complete the key
520  // check all the public keys of the loaded certificates
521  if (rsa) {
522  // Loop over the chain certificates
523  XrdCryptoX509 *cert = chain->Begin();
524  while (cert && cert->Opaque()) {
525  if (cert->type != XrdCryptoX509::kCA) {
526  // Get the public key
527  EVP_PKEY *evpp = X509_get_pubkey((X509 *)(cert->Opaque()));
528  if (evpp) {
529  // Test consistency
530 #if OPENSSL_VERSION_NUMBER < 0x30000000L
531  int rc = EVP_PKEY_cmp(evpp, rsa);
532 #else
533  int rc = EVP_PKEY_eq(evpp, rsa);
534 #endif
535  EVP_PKEY_free(evpp);
536  if (rc == 1) {
537  // Update PKI in certificate; also tests if the key is complete
538  cert->SetPKI((XrdCryptoX509data)rsa);
539  if (cert->PKI()->status == XrdCryptoRSA::kComplete) {
540  DEBUG("RSA key completed");
541  break;
542  }
543  }
544  }
545  }
546  // Get next
547  cert = chain->Next();
548  }
549  if (!cert)
550  EVP_PKEY_free(rsa);
551  }
552  else
553  EVP_PKEY_free(rsa);
554  }
555  if (fkey) {
556  // Re-establish original fcer pointer
557  fclose(fcer);
558  fcer = fcersave;
559  }
560  }
561 
562  // We are done
563  return nci;
564 }

References XrdCryptoX509Chain::Begin(), DEBUG, EPNAME, fclose(), fopen, XrdCryptoX509::kCA, XrdCryptoRSA::kComplete, XrdCryptoX509Chain::Next(), XrdCryptoX509::Opaque(), XrdCryptoX509::PKI(), XrdCryptoX509Chain::PushBack(), XrdCryptoX509::SetPKI(), XrdCryptoX509Chain::Size(), XrdCryptoRSA::status, XrdCryptoX509::Subject(), and XrdCryptoX509::type.

+ Here is the call graph for this function:

◆ XrdCryptosslX509ParseStack()

int XrdCryptosslX509ParseStack ( XrdTlsPeerCerts pc,
XrdCryptoX509Chain chain 
)

Definition at line 387 of file XrdCryptosslAux.cc.

388 {
389  EPNAME("X509ParseStack");
390  int nci = 0;
391  // Make sure we got a chain where to add the certificates
392  if (!chain) {
393  DEBUG("chain undefined: can do nothing");
394  return nci;
395  }
396 
397  if (pc->hasCert()) {
398  XrdCryptoX509 *c = new XrdCryptosslX509(pc->getCert());
399 
400  if (c) {
401  chain->PushBack(c);
402  nci ++;
403  }
404  }
405 
406  if (!pc->hasChain()) {
407  return nci;
408  }
409 
410  STACK_OF(X509) *pChain = pc->getChain();
411 
412  for (int i=0; i < sk_X509_num(pChain); i++) {
413  X509 *cert = sk_X509_value(pChain, i);
414  XrdCryptoX509 *c = new XrdCryptosslX509(cert);
415 
416  if (c) {
417  // The SSL_get_peer_chain method does not increment the
418  // refcount; the XrdCryptoX509 object assumes it owns
419  // the X509* but also does not increment the refcount.
420  // Hence, we increment manually.
421  X509_up_ref(cert);
422  chain->PushBack(c);
423  } else {
424  X509_free(cert);
425  DEBUG("could not create certificate: memory exhausted?");
426  chain->Reorder();
427  return nci;
428  }
429  nci ++;
430  }
431  chain->Reorder();
432  return nci;
433 }
void PushBack(XrdCryptoX509 *c)
X509 * getCert(bool upref=true)

References DEBUG, EPNAME, XrdTlsPeerCerts::getCert(), XrdTlsPeerCerts::hasCert(), XrdTlsPeerCerts::hasChain(), XrdCryptoX509Chain::PushBack(), and XrdCryptoX509Chain::Reorder().

Referenced by XrdCryptosslFactory::X509ParseStack().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ XrdCryptosslX509SignProxyReq()

int XrdCryptosslX509SignProxyReq ( XrdCryptoX509 ,
XrdCryptoRSA ,
XrdCryptoX509Req ,
XrdCryptoX509 **   
)

Referenced by XrdCryptosslFactory::X509SignProxyReq().

+ Here is the caller graph for this function:

◆ XrdCryptosslX509ToFile()

int XrdCryptosslX509ToFile ( XrdCryptoX509 x509,
FILE *  file,
const char *  fname 
)

Definition at line 287 of file XrdCryptosslAux.cc.

288 {
289  // Dump a single X509 certificate to a file in PEM format.
290  EPNAME("X509ChainToFile");
291 
292  // Check inputs
293  if (!x509 || !file) {
294  DEBUG("Invalid inputs");
295  return -1;
296  }
297 
298  if (PEM_write_X509(file, (X509 *)x509->Opaque()) != 1) {
299  DEBUG("error while writing certificate " << fname);
300  return -1;
301  }
302 
303  return 0;
304 }

References DEBUG, EPNAME, and XrdCryptoX509::Opaque().

+ Here is the call graph for this function:

◆ XrdCryptosslX509VerifyCert()

bool XrdCryptosslX509VerifyCert ( XrdCryptoX509 c,
XrdCryptoX509 r 
)

Definition at line 114 of file XrdCryptosslAux.cc.

115 {
116  // Verify signature of cert using public key of ref
117 
118  // Input must make sense
119  X509 *c = cert ? (X509 *)(cert->Opaque()) : 0;
120  X509 *r = ref ? (X509 *)(ref->Opaque()) : 0;
121  EVP_PKEY *rk = r ? X509_get_pubkey(r) : 0;
122  if (!c || !rk) return 0;
123 
124  // Ok: we can verify
125  return (X509_verify(c, rk) > 0);
126 }

References XrdCryptoX509::Opaque().

Referenced by XrdCryptosslFactory::X509VerifyCert().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ XrdCryptosslX509VerifyChain()

bool XrdCryptosslX509VerifyChain ( XrdCryptoX509Chain chain,
int &  errcode 
)

Definition at line 129 of file XrdCryptosslAux.cc.

130 {
131  // Verifies crossed signatures of X509 certificate 'chain'
132  // In case of failure, and error code is returned in errcode.
133 
134  // Make sure we got a potentially meaningful chain
135  if (!chain || chain->Size() <= 1)
136  return 0;
137 
138  // Create a store
139  X509_STORE *store = X509_STORE_new();
140  if (!store)
141  return 0;
142 
143  // Set the verify callback function
144  X509_STORE_set_verify_cb_func(store, 0);
145 
146  // Add the first (the CA) certificate
147  XrdCryptoX509 *cert = chain->Begin();
148  if (cert->type != XrdCryptoX509::kCA && cert->Opaque())
149  return 0;
150  X509_STORE_add_cert(store, (X509 *)(cert->Opaque()));
151 
152  // Create a stack
153  STACK_OF(X509) *stk = sk_X509_new_null();
154  if (!stk)
155  return 0;
156 
157  // Fill it with chain we have
158  X509 *cref = 0;
159  while ((cert = chain->Next()) && cert->Opaque()) {
160  if (!cref)
161  cref = (X509 *)(cert->Opaque());
162  sk_X509_push(stk, (X509 *)(cert->Opaque()));
163  }
164 
165  // Make sure all the certificates have been inserted
166  if (sk_X509_num(stk) != chain->Size() - 1)
167  return 0;
168 
169  // Create a store ctx ...
170  X509_STORE_CTX *ctx = X509_STORE_CTX_new();
171  if (!ctx)
172  return 0;
173 
174  // ... and initialize it
175  X509_STORE_CTX_init(ctx, store, cref, stk);
176 
177  // verify ?
178  bool verify_ok = (X509_verify_cert(ctx) == 1);
179 
180  // Fill error code, if any
181  errcode = 0;
182  if (!verify_ok)
183  errcode = gErrVerifyChain;
184 
185  // Free context, stack, and store
186  X509_STORE_CTX_free(ctx);
187  sk_X509_pop_free(stk, X509_free);
188  X509_STORE_free(store);
189 
190  return verify_ok;
191 }
static int gErrVerifyChain
XrdCryptoX509 * Next()
XrdCryptoX509 * Begin()

References XrdCryptoX509Chain::Begin(), gErrVerifyChain, XrdCryptoX509::kCA, XrdCryptoX509Chain::Next(), XrdCryptoX509::Opaque(), XrdCryptoX509Chain::Size(), and XrdCryptoX509::type.

Referenced by XrdCryptosslFactory::X509VerifyChain().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: