XRootD
XrdCryptoX509Chain Class Reference

#include <XrdCryptoX509Chain.hh>

+ Inheritance diagram for XrdCryptoX509Chain:
+ Collaboration diagram for XrdCryptoX509Chain:

Public Types

enum  ECAStatus {
  kUnknown = 0 ,
  kAbsent ,
  kInvalid ,
  kValid
}
 
enum  EX509ChainErr {
  kNone = 0 ,
  kInconsistent ,
  kTooMany ,
  kNoCA ,
  kNoCertificate ,
  kInvalidType ,
  kInvalidNames ,
  kRevoked ,
  kExpired ,
  kMissingExtension ,
  kVerifyFail ,
  kInvalidSign ,
  kCANotAutoSigned ,
  kNoEEC ,
  kTooManyEEC ,
  kInvalidProxy
}
 

Public Member Functions

 XrdCryptoX509Chain (XrdCryptoX509 *c=0)
 
 XrdCryptoX509Chain (XrdCryptoX509Chain *ch)
 
virtual ~XrdCryptoX509Chain ()
 
XrdCryptoX509 * Begin ()
 
const char * CAhash ()
 
const char * CAname ()
 
bool CheckCA (bool checkselfsigned=1)
 
virtual int CheckValidity (bool outatfirst=1, int when=0)
 
void Cleanup (bool keepCA=0)
 
void Dump ()
 
const char * EEChash ()
 
const char * EECname ()
 
XrdCryptoX509 * EffCA () const
 
XrdCryptoX509 * End () const
 
void InsertAfter (XrdCryptoX509 *c, XrdCryptoX509 *cp)
 
const char * LastError () const
 
XrdCryptoX509 * Next ()
 
void PushBack (XrdCryptoX509 *c)
 
void PutInFront (XrdCryptoX509 *c)
 
void Remove (XrdCryptoX509 *c)
 
virtual int Reorder ()
 
XrdCryptoX509 * SearchByIssuer (const char *issuer, ESearchMode mode=kExact)
 
XrdCryptoX509 * SearchBySubject (const char *subject, ESearchMode mode=kExact)
 
void SetStatusCA (ECAStatus st)
 
int Size () const
 
ECAStatus StatusCA () const
 
virtual bool Verify (EX509ChainErr &e, x509ChainVerifyOpt_t *vopt=0)
 
const char * X509ChainError (EX509ChainErr e)
 

Protected Member Functions

XrdCryptoX509ChainNode * Find (XrdCryptoX509 *c)
 
XrdCryptoX509ChainNode * FindIssuer (const char *issuer, ESearchMode mode=kExact, XrdCryptoX509ChainNode **p=0)
 
XrdCryptoX509ChainNode * FindSubject (const char *subject, ESearchMode mode=kExact, XrdCryptoX509ChainNode **p=0)
 
void SetEffectiveCA ()
 
bool Verify (EX509ChainErr &e, const char *msg, XrdCryptoX509::EX509Type type, int when, XrdCryptoX509 *xcer, XrdCryptoX509 *xsig, XrdCryptoX509Crl *crl=0)
 

Protected Attributes

XrdCryptoX509ChainNode * begin
 
XrdOucString cahash
 
XrdOucString caname
 
XrdCryptoX509ChainNode * current
 
XrdOucString eechash
 
XrdOucString eecname
 
XrdCryptoX509ChainNode * effca
 
XrdCryptoX509ChainNode * end
 
XrdOucString lastError
 
XrdCryptoX509ChainNode * previous
 
int size
 
ECAStatus statusCA
 

Detailed Description

Definition at line 80 of file XrdCryptoX509Chain.hh.

Member Enumeration Documentation

◆ ECAStatus

Enumerator
kUnknown 
kAbsent 
kInvalid 
kValid 

Definition at line 90 of file XrdCryptoX509Chain.hh.

◆ EX509ChainErr

Enumerator
kNone 
kInconsistent 
kTooMany 
kNoCA 
kNoCertificate 
kInvalidType 
kInvalidNames 
kRevoked 
kExpired 
kMissingExtension 
kVerifyFail 
kInvalidSign 
kCANotAutoSigned 
kNoEEC 
kTooManyEEC 
kInvalidProxy 

Definition at line 93 of file XrdCryptoX509Chain.hh.

Constructor & Destructor Documentation

◆ XrdCryptoX509Chain() [1/2]

XrdCryptoX509Chain::XrdCryptoX509Chain ( XrdCryptoX509 *  c = 0)

Definition at line 66 of file XrdCryptoX509Chain.cc.

67 {
68  // Constructor
69 
70  previous = 0;
71  current = 0;
72  begin = 0;
73  end = 0;
74  effca = 0;
75  size = 0;
76  lastError = "";
77  caname = "";
78  eecname = "";
79  cahash = "";
80  eechash = "";
82 
83  if (c) {
85  current = begin = end = f;
86  size++;
87  //
88  // If CA verify it and save result
89  if (c->type == XrdCryptoX509::kCA) {
90  caname = c->Subject();
91  cahash = c->SubjectHash();
92  EX509ChainErr ecode = kNone;
93  if (!Verify(ecode, "CA: ",XrdCryptoX509::kCA, 0, c, c))
95  else
96  statusCA = kValid;
97  }
98  // Search for the effective CA
100  }
101 }
virtual bool Verify(EX509ChainErr &e, x509ChainVerifyOpt_t *vopt=0)
XrdCryptoX509ChainNode * end
XrdCryptoX509ChainNode * begin
XrdCryptoX509ChainNode * previous
XrdCryptoX509ChainNode * current
XrdCryptoX509ChainNode * effca
virtual const char * Subject()
virtual const char * SubjectHash(int)
EX509Type type

References begin, cahash, caname, current, eechash, eecname, effca, end, XrdCryptoX509::kCA, kInvalid, kNone, kUnknown, kValid, lastError, previous, SetEffectiveCA(), size, statusCA, XrdCryptoX509::Subject(), XrdCryptoX509::SubjectHash(), XrdCryptoX509::type, and Verify().

+ Here is the call graph for this function:

◆ XrdCryptoX509Chain() [2/2]

XrdCryptoX509Chain::XrdCryptoX509Chain ( XrdCryptoX509Chain *  ch)

Definition at line 104 of file XrdCryptoX509Chain.cc.

105 {
106  // Copy constructor
107 
108  previous = 0;
109  current = 0;
110  begin = 0;
111  end = 0;
112  effca = 0;
113  size = 0;
114  lastError = ch->LastError();
115  caname = ch->CAname();
116  eecname = ch->EECname();
117  cahash = ch->CAhash();
118  eechash = ch->EEChash();
119  statusCA = ch->StatusCA();
120 
121  XrdCryptoX509 *c = ch->Begin();
122  while (c) {
124  if (!begin)
125  begin = nc;
126  if (end)
127  end->SetNext(nc);
128  end = nc;
129  if (c == ch->EffCA()) effca = nc;
130  size++;
131  // Go to Next
132  c = ch->Next();
133  }
134 }
void SetNext(XrdCryptoX509ChainNode *n)
XrdCryptoX509 * Next()
XrdCryptoX509 * Begin()
ECAStatus StatusCA() const
XrdCryptoX509 * EffCA() const
const char * LastError() const

References Begin(), begin, CAhash(), cahash, CAname(), caname, current, EEChash(), eechash, EECname(), eecname, EffCA(), effca, end, LastError(), lastError, Next(), previous, XrdCryptoX509ChainNode::SetNext(), size, StatusCA(), and statusCA.

+ Here is the call graph for this function:

◆ ~XrdCryptoX509Chain()

XrdCryptoX509Chain::~XrdCryptoX509Chain ( )
virtual

Definition at line 137 of file XrdCryptoX509Chain.cc.

138 {
139  // Destructor
140 
141  XrdCryptoX509ChainNode *n = 0;
143  while (c) {
144  n = c->Next();
145  delete (c);
146  c = n;
147  }
148 }
XrdCryptoX509ChainNode * Next() const

References begin, and XrdCryptoX509ChainNode::Next().

+ Here is the call graph for this function:

Member Function Documentation

◆ Begin()

XrdCryptoX509 * XrdCryptoX509Chain::Begin ( )

Definition at line 380 of file XrdCryptoX509Chain.cc.

381 {
382  // Iterator functionality: init
383 
384  previous = 0;
385  current = begin;
386  if (current)
387  return current->Cert();
388  return (XrdCryptoX509 *)0;
389 }
XrdCryptoX509 * Cert() const

References begin, XrdCryptoX509ChainNode::Cert(), current, and previous.

Referenced by XrdCryptoX509Chain(), XrdSecProtocolgsi::getCredentials(), main(), XrdVomsFun::VOMSFun(), XrdCryptosslX509ExportChain(), XrdCryptosslX509ParseBucket(), XrdCryptosslX509ParseFile(), and XrdCryptosslX509VerifyChain().

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

◆ CAhash()

const char * XrdCryptoX509Chain::CAhash ( )

Definition at line 891 of file XrdCryptoX509Chain.cc.

892 {
893  // Return the subject name hash of the CA in the chain
894  EPNAME("X509Chain::CAhash");
895 
896  // If we do not have it already, try extraction
897  if (cahash.length() <= 0 && statusCA == kUnknown) {
898 
899  if (!CheckCA()) {
900  DEBUG("CA not found in chain");
901  return (const char *)0;
902  }
903  }
904 
905  // return what we have
906  return (cahash.length() > 0) ? cahash.c_str() : (const char *)0;
907 }
#define DEBUG(x)
Definition: XrdBwmTrace.hh:54
#define EPNAME(x)
Definition: XrdBwmTrace.hh:56
bool CheckCA(bool checkselfsigned=1)
const char * c_str() const
int length() const

References XrdOucString::c_str(), cahash, CheckCA(), DEBUG, EPNAME, kUnknown, XrdOucString::length(), and statusCA.

Referenced by XrdCryptoX509Chain().

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

◆ CAname()

const char * XrdCryptoX509Chain::CAname ( )

Definition at line 845 of file XrdCryptoX509Chain.cc.

846 {
847  // Return subject name of the CA in the chain
848  EPNAME("X509Chain::CAname");
849 
850  // If we do not have it already, try extraction
851  if (caname.length() <= 0 && statusCA == kUnknown) {
852 
853  if (!CheckCA()) {
854  DEBUG("CA not found in chain");
855  return (const char *)0;
856  }
857  }
858 
859  // return what we have
860  return (caname.length() > 0) ? caname.c_str() : (const char *)0;
861 }

References XrdOucString::c_str(), caname, CheckCA(), DEBUG, EPNAME, kUnknown, XrdOucString::length(), and statusCA.

Referenced by XrdCryptoX509Chain(), and Dump().

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

◆ CheckCA()

bool XrdCryptoX509Chain::CheckCA ( bool  checkselfsigned = 1)

Definition at line 183 of file XrdCryptoX509Chain.cc.

184 {
185  // Search the list for a valid CA and set it at top.
186  // Search stops when a valid CA is found; an invalid CA is flagged.
187  // A second CA is always ignored.
188  // Signature check failures are accepted if 'checkselfsigned' is false.
189  // Return 1 if found, 0 otherwise; lastError is filled with the reason of
190  // failure, if any.
191 
192  XrdCryptoX509 *xc = 0;
193  XrdCryptoX509ChainNode *n = 0;
195  XrdCryptoX509ChainNode *p = 0;
196  lastError = "";
197  while (c) {
198  n = c->Next();
199  xc = c->Cert();
200  if (xc && xc->type == XrdCryptoX509::kCA) {
201  caname = xc->Subject();
202  cahash = xc->SubjectHash();
203  EX509ChainErr ecode = kNone;
204  bool CAok = Verify(ecode, "CA: ",XrdCryptoX509::kCA, 0, xc, xc);
205  if (!CAok && (ecode != kVerifyFail || checkselfsigned)) {
206  statusCA = kInvalid;
207  lastError += X509ChainError(ecode);
208  } else {
209  statusCA = kValid;
210  if (p) {
211  // Move at top
212  p->SetNext(c->Next());
213  c->SetNext(begin);
214  if (end == c) end = p;
215  begin = c;
216  }
217  return 1;
218  }
219  }
220  p = c; // Previous node
221  c = n;
222  }
223 
224  // Found nothing
225  return 0;
226 }
const char * X509ChainError(EX509ChainErr e)

References begin, cahash, caname, XrdCryptoX509ChainNode::Cert(), end, XrdCryptoX509::kCA, kInvalid, kNone, kValid, kVerifyFail, lastError, XrdCryptoX509ChainNode::Next(), XrdCryptoX509ChainNode::SetNext(), statusCA, XrdCryptoX509::Subject(), XrdCryptoX509::SubjectHash(), XrdCryptoX509::type, Verify(), and X509ChainError().

Referenced by CAhash(), CAname(), and Verify().

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

◆ CheckValidity()

int XrdCryptoX509Chain::CheckValidity ( bool  outatfirst = 1,
int  when = 0 
)
virtual

Definition at line 747 of file XrdCryptoX509Chain.cc.

748 {
749  // Check validity at 'when' of certificates in the chain and return
750  // the number of invalid certificates.
751  // If 'outatfirst' return after the first invalid has been
752  // found.
753  EPNAME("X509Chain::CheckValidity");
754  int ninv = 0;
755 
756  // Do nothing if empty
757  if (size < 1) {
758  DEBUG("Nothing to verify (size: "<<size<<")");
759  return ninv;
760  }
761 
762  // Loop over the certificates
764  while (nc) {
765  //
766  XrdCryptoX509 *c = nc->Cert();
767  if (c) {
768  if (!(c->IsValid(when))) {
769  ninv++;
770  DEBUG("invalid certificate found");
771  if (outatfirst)
772  return ninv;
773  }
774  } else {
775  ninv++;
776  DEBUG("found node without certificate");
777  if (outatfirst)
778  return ninv;
779  }
780  // Get next
781  nc = nc->Next();
782  }
783 
784  // We are done
785  return ninv;
786 }
virtual bool IsValid(int when=0)

References begin, XrdCryptoX509ChainNode::Cert(), DEBUG, EPNAME, XrdCryptoX509::IsValid(), XrdCryptoX509ChainNode::Next(), and size.

Referenced by GetCACheck(), and QueryProxyCheck().

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

◆ Cleanup()

void XrdCryptoX509Chain::Cleanup ( bool  keepCA = 0)

Definition at line 151 of file XrdCryptoX509Chain.cc.

152 {
153  // Destructs content of nodes AND their content
154  // If keepCA is true, the top CA is kept
155 
156  XrdCryptoX509ChainNode *n = 0;
158  while (c) {
159  n = c->Next();
160  if (c->Cert() &&
161  (!keepCA || (c->Cert()->type != XrdCryptoX509::kCA)))
162  delete (c->Cert());
163  delete (c);
164  c = n;
165  }
166 
167  // Reset
168  previous = 0;
169  current = 0;
170  begin = 0;
171  end = 0;
172  effca = 0;
173  size = 0;
174  lastError = "";
175  caname = "";
176  eecname = "";
177  cahash = "";
178  eechash = "";
179  statusCA = kUnknown;
180 }

References begin, cahash, caname, XrdCryptoX509ChainNode::Cert(), current, eechash, eecname, effca, end, XrdCryptoX509::kCA, kUnknown, lastError, XrdCryptoX509ChainNode::Next(), previous, size, statusCA, and XrdCryptoX509::type.

Referenced by gsiHSVars::~gsiHSVars(), and XrdSecProtocolgsi::Delete().

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

◆ Dump()

void XrdCryptoX509Chain::Dump ( )

Definition at line 523 of file XrdCryptoX509Chain.cc.

524 {
525  // Dump content
526  EPNAME("X509Chain::Dump");
527 
528  LOCDUMP("//------------------Dumping X509 chain content ------------------//");
529  LOCDUMP("//");
530  LOCDUMP("// Chain instance: "<<this);
531  LOCDUMP("//");
532  LOCDUMP("// Number of certificates: "<<Size());
533  LOCDUMP("//");
534  if (CAname()) {
535  LOCDUMP("// CA: "<<CAname());
536  } else {
537  LOCDUMP("// CA: absent");
538  }
539  if (EECname()) {
540  LOCDUMP("// EEC: "<<EECname());
541  } else {
542  LOCDUMP("// EEC: absent");
543  }
544  LOCDUMP("//");
545  XrdCryptoX509ChainNode *n = 0;
547  while (c) {
548  n = c->Next();
549  if (c->Cert()) {
550  LOCDUMP("// Issuer: "<<c->Cert()->IssuerHash()<<
551  " Subject: "<<c->Cert()->SubjectHash()<<
552  " Type: "<<c->Cert()->Type());
553  }
554  c = n;
555  }
556  LOCDUMP("//");
557  LOCDUMP("//---------------------------- END ------------------------------//")
558 }
#define LOCDUMP(y)
const char * Type(EX509Type t=kUnknown) const
virtual const char * IssuerHash(int)

References begin, CAname(), XrdCryptoX509ChainNode::Cert(), EECname(), EPNAME, XrdCryptoX509::IssuerHash(), LOCDUMP, XrdCryptoX509ChainNode::Next(), Size(), XrdCryptoX509::SubjectHash(), and XrdCryptoX509::Type().

Referenced by main(), and XrdCryptogsiX509Chain::Verify().

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

◆ EEChash()

const char * XrdCryptoX509Chain::EEChash ( )

Definition at line 910 of file XrdCryptoX509Chain.cc.

911 {
912  // Return the subject name hash of the EEC in the chain
913  EPNAME("X509Chain::EEChash");
914 
915  // If we do not have it already, try extraction
916  if (eechash.length() <= 0) {
917 
919  while (c) {
920  if (c->Cert()->type == XrdCryptoX509::kEEC) {
921  eechash = c->Cert()->SubjectHash();
922  break;
923  }
924  c = c->Next();
925  }
926  if (eechash.length() <= 0) {
927  DEBUG("EEC not found in chain");
928  return (const char *)0;
929  }
930  }
931 
932  // return what we have
933  return (eechash.length() > 0) ? eechash.c_str() : (const char *)0;
934 }

References begin, XrdOucString::c_str(), XrdCryptoX509ChainNode::Cert(), DEBUG, eechash, EPNAME, XrdCryptoX509::kEEC, XrdOucString::length(), XrdCryptoX509ChainNode::Next(), XrdCryptoX509::SubjectHash(), and XrdCryptoX509::type.

Referenced by XrdCryptoX509Chain(), and XrdSecProtocolgsi::Authenticate().

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

◆ EECname()

const char * XrdCryptoX509Chain::EECname ( )

Definition at line 864 of file XrdCryptoX509Chain.cc.

865 {
866  // Return subject name of the EEC in the chain
867  EPNAME("X509Chain::EECname");
868 
869  // If we do not have it already, try extraction
870  if (eecname.length() <= 0) {
871 
873  while (c) {
874  if (c->Cert()->type == XrdCryptoX509::kEEC) {
875  eecname = c->Cert()->Subject();
876  break;
877  }
878  c = c->Next();
879  }
880  if (eecname.length() <= 0) {
881  DEBUG("EEC not found in chain");
882  return (const char *)0;
883  }
884  }
885 
886  // return what we have
887  return (eecname.length() > 0) ? eecname.c_str() : (const char *)0;
888 }

References begin, XrdOucString::c_str(), XrdCryptoX509ChainNode::Cert(), DEBUG, eecname, EPNAME, XrdCryptoX509::kEEC, XrdOucString::length(), XrdCryptoX509ChainNode::Next(), XrdCryptoX509::Subject(), and XrdCryptoX509::type.

Referenced by XrdCryptoX509Chain(), XrdSecProtocolgsi::Authenticate(), and Dump().

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

◆ EffCA()

XrdCryptoX509* XrdCryptoX509Chain::EffCA ( ) const
inline

Definition at line 114 of file XrdCryptoX509Chain.hh.

114 { return effca ? effca->Cert() : (XrdCryptoX509 *)0; }

References XrdCryptoX509ChainNode::Cert(), and effca.

Referenced by XrdCryptoX509Chain().

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

◆ End()

XrdCryptoX509* XrdCryptoX509Chain::End ( ) const
inline

Definition at line 108 of file XrdCryptoX509Chain.hh.

108 { return end->Cert(); }

References XrdCryptoX509ChainNode::Cert(), and end.

Referenced by XrdSecProtocolgsi::Authenticate(), main(), XrdVomsFun::VOMSFun(), XrdCryptosslX509ChainToFile(), XrdCryptosslX509ExportChain(), and XrdSecgsiAuthzKey().

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

◆ Find()

XrdCryptoX509ChainNode * XrdCryptoX509Chain::Find ( XrdCryptoX509 *  c)
protected

Definition at line 237 of file XrdCryptoX509Chain.cc.

238 {
239  // Find node containing bucket b
240 
242  for (; nd; nd = nd->Next()) {
243  if (nd->Cert() == c)
244  return nd;
245  }
246  return (XrdCryptoX509ChainNode *)0;
247 }

References begin, XrdCryptoX509ChainNode::Cert(), and XrdCryptoX509ChainNode::Next().

Referenced by InsertAfter(), PushBack(), and PutInFront().

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

◆ FindIssuer()

XrdCryptoX509ChainNode * XrdCryptoX509Chain::FindIssuer ( const char *  issuer,
ESearchMode  mode = kExact,
XrdCryptoX509ChainNode **  p = 0 
)
protected

Definition at line 433 of file XrdCryptoX509Chain.cc.

435 {
436  // Return first chain node with certificate having issuer
437  // Match according to mode.
438 
439  // Make sure we got something to compare
440  if (!issuer)
441  return (XrdCryptoX509ChainNode *)0;
442 
443  XrdCryptoX509ChainNode *cp = 0;
444  XrdCryptoX509ChainNode *n = 0;
446  XrdCryptoX509 *c = 0;
447  while (cn) {
448  n = cn->Next();
449  c = cn->Cert();
450  if(c) {
451  const char *pi = c->Issuer();
452  if (pi) {
453  if (mode == kExact) {
454  if (!strcmp(pi, issuer))
455  break;
456  } else if (mode == kBegin) {
457  if (strstr(pi, issuer) == c->Issuer())
458  break;
459  } else if (mode == kEnd) {
460  int ibeg = strlen(pi) - strlen(issuer);
461  if (!strcmp(pi + ibeg, issuer))
462  break;
463  }
464  }
465  }
466  c = 0;
467  cp = cn; // previous
468  cn = n;
469  }
470  // return previous, if requested
471  if (prev)
472  *prev = (cn) ? cp : 0;
473 
474  // We are done
475  return ((cn) ? cn : (XrdCryptoX509ChainNode *)0);
476 }
virtual const char * Issuer()

References begin, XrdCryptoX509ChainNode::Cert(), XrdCryptoX509::Issuer(), and XrdCryptoX509ChainNode::Next().

Referenced by SearchByIssuer().

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

◆ FindSubject()

XrdCryptoX509ChainNode * XrdCryptoX509Chain::FindSubject ( const char *  subject,
ESearchMode  mode = kExact,
XrdCryptoX509ChainNode **  p = 0 
)
protected

Definition at line 479 of file XrdCryptoX509Chain.cc.

481 {
482  // Return first chain node with certificate having subject
483  // Match according to mode.
484 
485  // Make sure we got something to compare
486  if (!subject)
487  return (XrdCryptoX509ChainNode *)0;
488 
489  XrdCryptoX509ChainNode *cp = 0;
490  XrdCryptoX509ChainNode *n = 0;
492  XrdCryptoX509 *c = 0;
493  while (cn) {
494  n = cn->Next();
495  c = cn->Cert();
496  const char *ps = c ? c->Subject() : 0;
497  if (c && ps) {
498  if (mode == kExact) {
499  if (!strcmp(ps, subject))
500  break;
501  } else if (mode == kBegin) {
502  if (strstr(ps, subject) == ps)
503  break;
504  } else if (mode == kEnd) {
505  int sbeg = strlen(ps) - strlen(subject);
506  if (!strcmp(ps + sbeg, subject))
507  break;
508  }
509  }
510  c = 0;
511  cp = cn; // previous
512  cn = n;
513  }
514  // return previous, if requested
515  if (prev)
516  *prev = (cn) ? cp : 0;
517 
518  // We are done
519  return ((cn) ? cn : (XrdCryptoX509ChainNode *)0);
520 }

References begin, XrdCryptoX509ChainNode::Cert(), XrdCryptoX509ChainNode::Next(), and XrdCryptoX509::Subject().

Referenced by Reorder(), and SearchBySubject().

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

◆ InsertAfter()

void XrdCryptoX509Chain::InsertAfter ( XrdCryptoX509 *  c,
XrdCryptoX509 *  cp 
)

Definition at line 268 of file XrdCryptoX509Chain.cc.

269 {
270  // Add or move certificate 'c' after certificate 'cp'; if 'cp' is not
271  // in the list, push-back
272 
273  XrdCryptoX509ChainNode *nc = Find(c);
274  XrdCryptoX509ChainNode *ncp = Find(cp);
275  if (ncp) {
276  // Create a new node, if not there
277  if (!nc) {
278  nc = new XrdCryptoX509ChainNode(c,ncp->Next());
279  size++;
280  }
281  // Update pointers
282  ncp->SetNext(nc);
283  if (end == ncp)
284  end = nc;
285 
286  } else {
287  // Reference certificate not in the list
288  // If new, add in last position; otherwise leave it where it is
289  if (!nc)
290  PushBack(c);
291  }
292 
293  // Search for the effective CA (the last one, in case of subCAs)
294  SetEffectiveCA();
295 }
void PushBack(XrdCryptoX509 *c)
XrdCryptoX509ChainNode * Find(XrdCryptoX509 *c)

References end, Find(), XrdCryptoX509ChainNode::Next(), PushBack(), SetEffectiveCA(), XrdCryptoX509ChainNode::SetNext(), and size.

+ Here is the call graph for this function:

◆ LastError()

const char* XrdCryptoX509Chain::LastError ( ) const
inline

Definition at line 101 of file XrdCryptoX509Chain.hh.

101 { return lastError.c_str(); }

References XrdOucString::c_str(), and lastError.

Referenced by XrdCryptoX509Chain(), and main().

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

◆ Next()

XrdCryptoX509 * XrdCryptoX509Chain::Next ( )

Definition at line 392 of file XrdCryptoX509Chain.cc.

393 {
394  // Iterator functionality: get next
395 
396  previous = current;
397  if (current) {
398  current = current->Next();
399  if (current)
400  return current->Cert();
401  }
402  return (XrdCryptoX509 *)0;
403 }

References XrdCryptoX509ChainNode::Cert(), current, XrdCryptoX509ChainNode::Next(), and previous.

Referenced by XrdCryptoX509Chain(), XrdSecProtocolgsi::getCredentials(), XrdVomsFun::VOMSFun(), XrdCryptosslX509ParseBucket(), XrdCryptosslX509ParseFile(), and XrdCryptosslX509VerifyChain().

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

◆ PushBack()

void XrdCryptoX509Chain::PushBack ( XrdCryptoX509 *  c)

Definition at line 298 of file XrdCryptoX509Chain.cc.

299 {
300  // Add at the end of the list
301  // Check to avoid duplicates
302 
303  if (!Find(c)) {
305  if (!begin)
306  begin = nc;
307  if (end)
308  end->SetNext(nc);
309  end = nc;
310  size++;
311  } else if (c) {
312  delete c;
313  }
314 
315  // Search for the effective CA (the last one, in case of subCAs)
316  SetEffectiveCA();
317 }

References begin, end, Find(), SetEffectiveCA(), XrdCryptoX509ChainNode::SetNext(), and size.

Referenced by InsertAfter(), main(), XrdCryptosslX509ParseBucket(), XrdCryptosslX509ParseFile(), and XrdCryptosslX509ParseStack().

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

◆ PutInFront()

void XrdCryptoX509Chain::PutInFront ( XrdCryptoX509 *  c)

Definition at line 250 of file XrdCryptoX509Chain.cc.

251 {
252  // Add at the beginning of the list
253  // Check to avoid duplicates
254 
255  if (!Find(c)) {
257  begin = nc;
258  if (!end)
259  end = nc;
260  size++;
261  }
262 
263  // Search for the effective CA (the last one, in case of subCAs)
264  SetEffectiveCA();
265 }

References begin, end, Find(), SetEffectiveCA(), and size.

+ Here is the call graph for this function:

◆ Remove()

void XrdCryptoX509Chain::Remove ( XrdCryptoX509 *  c)

Definition at line 320 of file XrdCryptoX509Chain.cc.

321 {
322  // Remove node containing bucket b
323 
326 
327  if (!curr || curr->Cert() != c || (prev && curr != prev->Next())) {
328  // We need first to find the address
329  curr = begin;
330  prev = 0;
331  for (; curr; curr = curr->Next()) {
332  if (curr->Cert() == c)
333  break;
334  prev = curr;
335  }
336  }
337 
338  // The certificate is not in the list
339  if (!curr)
340  return;
341 
342  //
343  // If this was the top CA update the related information
344  if (c->type == XrdCryptoX509::kCA && curr == begin) {
345  // There may be other CAs in the chain, but we will
346  // check when needed
347  statusCA = kUnknown;
348  caname = "";
349  cahash = "";
350  }
351 
352  // Now we have all the information to remove
353  if (prev) {
354  if (curr != end) {
355  current = curr->Next();
356  prev->SetNext(current);
357  previous = prev;
358  } else {
359  end = prev;
360  previous = end;
361  current = 0;
362  prev->SetNext(current);
363  }
364  } else if (curr == begin) {
365  // First buffer
366  current = curr->Next();
367  begin = current;
368  previous = 0;
369  }
370 
371  // Cleanup and update size
372  delete curr;
373  size--;
374 
375  // Search for the effective CA (the last one, in case of subCAs)
376  SetEffectiveCA();
377 }

References begin, cahash, caname, XrdCryptoX509ChainNode::Cert(), current, end, XrdCryptoX509::kCA, kUnknown, XrdCryptoX509ChainNode::Next(), previous, SetEffectiveCA(), XrdCryptoX509ChainNode::SetNext(), size, statusCA, and XrdCryptoX509::type.

+ Here is the call graph for this function:

◆ Reorder()

int XrdCryptoX509Chain::Reorder ( )
virtual

Definition at line 561 of file XrdCryptoX509Chain.cc.

562 {
563  // Reorder certificates in such a way that certificate n is the
564  // issuer of certificate n+1 .
565  // Return -1 if inconsistencies are found.
566  EPNAME("X509Chain::Reorder");
567 
568  if (size < 2) {
569  DEBUG("Nothing to reorder (size: "<<size<<")");
570  // Search for the effective CA (the last one, in case of subCAs)
571  SetEffectiveCA();
572  return 0;
573  }
574 
575  // Loop over the certificates
576  XrdCryptoX509ChainNode *nc = 0, *np = 0, *nn = 0, *nr = 0, *npp = 0;
577 
578  // Look for the first one, if needed
579  nr = begin;
580  np = nr;
581  while (nr) {
582  //
583  if (!(nn = FindSubject(nr->Cert()->Issuer(),kExact,&npp)) ||
584  nn == nr)
585  break;
586  np = nr;
587  nr = nr->Next();
588  }
589 
590  // Move it in first position if not yet there
591  if (nr && nr != begin) {
592  np->SetNext(nr->Next()); // short cut old position
593  nr->SetNext(begin); // set our next to present begin
594  if (end == nr) // Update end
595  end = np;
596  begin = nr; // set us as begin
597  // Flag if not CA: we do not check validity here
598  if (nr->Cert()->type != XrdCryptoX509::kCA) {
599  statusCA = kAbsent;
600  } else if (caname.length() <= 0) {
601  // Set the CA properties only if not done already to avoid overwriting
602  // the result of previous analysis
603  caname = nr->Cert()->Subject();
604  cahash = nr->Cert()->SubjectHash();
605  statusCA = kUnknown;
606  }
607  }
608 
609  int left = size-1;
610  np = begin;
611  while (np) {
612  if (np->Cert()) {
613  const char *pi = np->Cert()->Subject();
614  // Set the EEC name, if not yet done
615  if (np->Cert()->type == XrdCryptoX509::kEEC && eecname.length() <= 0) {
616  eecname = pi;
617  eechash = np->Cert()->SubjectHash();
618  }
619  npp = np;
620  nc = np->Next();
621  while (nc) {
622  if (nc->Cert() && !strcmp(pi, nc->Cert()->Issuer())) {
623  left--;
624  if (npp != np) {
625  npp->SetNext(nc->Next()); // drop child from previous pos
626  nc->SetNext(np->Next()); // set child next as our present
627  np->SetNext(nc); // set our next as child
628  if (nc == end)
629  end = npp;
630  }
631  break;
632  }
633  npp = nc;
634  nc = nc->Next();
635  }
636  }
637  np = np->Next();
638  }
639 
640  // Search for the effective CA (the last one, in case of subCAs)
641  SetEffectiveCA();
642 
643  // Check consistency
644  if (left > 0) {
645  DEBUG("Inconsistency found: "<<left<<
646  " certificates could not be correctly enchained!");
647  return -1;
648  }
649 
650  // We are done
651  return 0;
652 }
XrdCryptoX509ChainNode * FindSubject(const char *subject, ESearchMode mode=kExact, XrdCryptoX509ChainNode **p=0)

References begin, cahash, caname, XrdCryptoX509ChainNode::Cert(), DEBUG, eechash, eecname, end, EPNAME, FindSubject(), XrdCryptoX509::Issuer(), kAbsent, XrdCryptoX509::kCA, XrdCryptoX509::kEEC, kUnknown, XrdOucString::length(), XrdCryptoX509ChainNode::Next(), SetEffectiveCA(), XrdCryptoX509ChainNode::SetNext(), size, statusCA, and XrdCryptoX509::Subject().

Referenced by main(), XrdCryptogsiX509Chain::Verify(), Verify(), XrdCryptosslX509ChainToFile(), XrdCryptosslX509ExportChain(), XrdCryptosslX509ParseStack(), and XrdSecgsiAuthzKey().

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

◆ SearchByIssuer()

XrdCryptoX509 * XrdCryptoX509Chain::SearchByIssuer ( const char *  issuer,
ESearchMode  mode = kExact 
)

Definition at line 406 of file XrdCryptoX509Chain.cc.

408 {
409  // Return first certificate in the chain with issuer
410  // Match according to mode.
411 
412  XrdCryptoX509ChainNode *cn = FindIssuer(issuer, mode);
413 
414  // We are done
415  return ((cn) ? cn->Cert() : (XrdCryptoX509 *)0);
416 }
XrdCryptoX509ChainNode * FindIssuer(const char *issuer, ESearchMode mode=kExact, XrdCryptoX509ChainNode **p=0)

References XrdCryptoX509ChainNode::Cert(), and FindIssuer().

+ Here is the call graph for this function:

◆ SearchBySubject()

XrdCryptoX509 * XrdCryptoX509Chain::SearchBySubject ( const char *  subject,
ESearchMode  mode = kExact 
)

Definition at line 419 of file XrdCryptoX509Chain.cc.

421 {
422  // Return first certificate in the chain with subject
423  // Match according to mode.
424 
425  XrdCryptoX509ChainNode *cn = FindSubject(subject, mode);
426 
427  // We are done
428  return ((cn) ? cn->Cert() : (XrdCryptoX509 *)0);
429 
430 }

References XrdCryptoX509ChainNode::Cert(), and FindSubject().

Referenced by XrdCryptosslX509ChainToFile(), and XrdCryptosslX509ExportChain().

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

◆ SetEffectiveCA()

void XrdCryptoX509Chain::SetEffectiveCA ( )
protected

Definition at line 655 of file XrdCryptoX509Chain.cc.

656 {
657  // Search for the effective CA (the last one, in case of subCAs)
658  effca = 0; caname = ""; cahash = "";
659 
661  while (np) {
662  if (np->Cert()) {
663  if (np->Cert()->type == XrdCryptoX509::kCA) {
664  if (!effca || (effca &&
665  !(strcmp(effca->Cert()->SubjectHash(),
666  np->Cert()->IssuerHash())))) effca = np;
667  }
668  }
669  np = np->Next();
670  }
671  if (effca && effca->Cert()) {
672  caname = effca->Cert()->Subject();
673  cahash = effca->Cert()->SubjectHash();
674  }
675 }

References begin, cahash, caname, XrdCryptoX509ChainNode::Cert(), effca, XrdCryptoX509::IssuerHash(), XrdCryptoX509::kCA, XrdCryptoX509ChainNode::Next(), XrdCryptoX509::Subject(), XrdCryptoX509::SubjectHash(), and XrdCryptoX509::type.

Referenced by XrdCryptoX509Chain(), InsertAfter(), PushBack(), PutInFront(), Remove(), and Reorder().

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

◆ SetStatusCA()

void XrdCryptoX509Chain::SetStatusCA ( ECAStatus  st)
inline

Definition at line 123 of file XrdCryptoX509Chain.hh.

123 { statusCA = st; }

References statusCA.

◆ Size()

int XrdCryptoX509Chain::Size ( ) const
inline

Definition at line 107 of file XrdCryptoX509Chain.hh.

107 { return size; }

References size.

Referenced by Dump(), XrdCryptosslX509ExportChain(), XrdCryptosslX509ParseBucket(), XrdCryptosslX509ParseFile(), and XrdCryptosslX509VerifyChain().

+ Here is the caller graph for this function:

◆ StatusCA()

ECAStatus XrdCryptoX509Chain::StatusCA ( ) const
inline

Definition at line 109 of file XrdCryptoX509Chain.hh.

109 { return statusCA; }

References statusCA.

Referenced by XrdCryptoX509Chain().

+ Here is the caller graph for this function:

◆ Verify() [1/2]

bool XrdCryptoX509Chain::Verify ( EX509ChainErr &  e,
const char *  msg,
XrdCryptoX509::EX509Type  type,
int  when,
XrdCryptoX509 *  xcer,
XrdCryptoX509 *  xsig,
XrdCryptoX509Crl *  crl = 0 
)
protected

Definition at line 789 of file XrdCryptoX509Chain.cc.

793 {
794  // Internal verification method
795 
796  // Certificate must be defined
797  if (!xcer) {
798  errcode = kNoCertificate;
799  lastError = msg;
800  lastError += X509ChainError(errcode);
801  return 0;
802  }
803 
804  // Type should be the one expected
805  if (type != XrdCryptoX509::kUnknown && xcer->type != type) {
806  errcode = kInvalidType;
807  lastError = msg;
808  lastError += X509ChainError(errcode);
809  return 0;
810  }
811 
812  // Must not be revoked (check only if required)
813  if (crl) {
814  // Get certificate serial number
815  XrdOucString sn = xcer->SerialNumberString();
816  if (crl->IsRevoked(sn.c_str(), when)) {
817  errcode = kRevoked;
818  lastError = msg;
819  lastError += X509ChainError(errcode);
820  return 0;
821  }
822  }
823 
824  // Check validity in time
825  if (when >= 0 && !(xcer->IsValid(when))) {
826  errcode = kExpired;
827  lastError = msg;
828  lastError += X509ChainError(errcode);
829  return 0;
830  }
831 
832  // Check signature
833  if (!xsig || !(xcer->Verify(xsig))) {
834  errcode = kVerifyFail;
835  lastError = msg;
836  lastError += X509ChainError(errcode);
837  return 0;
838  }
839 
840  // We are done
841  return 1;
842 }
virtual bool IsRevoked(int serialnumber, int when)
virtual bool Verify(XrdCryptoX509 *ref)
virtual XrdOucString SerialNumberString()

References XrdOucString::c_str(), XrdCryptoX509Crl::IsRevoked(), XrdCryptoX509::IsValid(), kExpired, kInvalidType, kNoCertificate, kRevoked, XrdCryptoX509::kUnknown, kVerifyFail, lastError, XrdCryptoX509::SerialNumberString(), XrdCryptoX509::type, XrdCryptoX509::Verify(), and X509ChainError().

+ Here is the call graph for this function:

◆ Verify() [2/2]

bool XrdCryptoX509Chain::Verify ( EX509ChainErr &  e,
x509ChainVerifyOpt_t *  vopt = 0 
)
virtual

Reimplemented in XrdCryptogsiX509Chain.

Definition at line 678 of file XrdCryptoX509Chain.cc.

679 {
680  // Verify cross signatures of the chain
681  EPNAME("X509Chain::Verify");
682  errcode = kNone;
683 
684  // Do nothing if empty
685  if (size < 1) {
686  DEBUG("Nothing to verify (size: "<<size<<")");
687  return 0;
688  }
689 
690  //
691  // Reorder if needed
692  if (Reorder() != 0) {
693  errcode = kInconsistent;
694  lastError = ":";
695  lastError += X509ChainError(errcode);
696  return 0;
697  }
698 
699  //
700  // Verification options
701  int when = (vopt) ? vopt->when : (int)time(0);
702  int plen = (vopt) ? vopt->pathlen : -1;
703  bool chkss = (vopt) ? (vopt->opt & kOptsCheckSelfSigned) : 1;
704 
705  //
706  // Global path depth length consistency check
707  if (plen > -1 && plen < size) {
708  errcode = kTooMany;
709  lastError = "checking path depth: ";
710  lastError += X509ChainError(errcode);
711  }
712 
713  //
714  // Check the first certificate: it MUST be of CA type, valid,
715  // self-signed
716  if (!CheckCA(chkss)) {
717  errcode = kNoCA;
718  lastError = X509ChainError(errcode);
719  return 0;
720  }
721 
722  //
723  // Analyse the rest
725  XrdCryptoX509 *xsig = node->Cert(); // Signing certificate
726  XrdCryptoX509 *xcer = 0; // Certificate under exam
727  node = node->Next();
728  while (node) {
729 
730  // Attache to certificate
731  xcer = node->Cert();
732 
733  // Standard verification
734  if (!Verify(errcode, "cert: ", XrdCryptoX509::kUnknown, when, xcer, xsig))
735  return 0;
736 
737  // Get next
738  xsig = xcer;
739  node = node->Next();
740  }
741 
742  // We are done (successfully!)
743  return 1;
744 }
const int kOptsCheckSelfSigned

References begin, XrdCryptoX509ChainNode::Cert(), CheckCA(), DEBUG, EPNAME, kInconsistent, kNoCA, kNone, kOptsCheckSelfSigned, kTooMany, XrdCryptoX509::kUnknown, lastError, XrdCryptoX509ChainNode::Next(), x509ChainVerifyOpt_t::opt, x509ChainVerifyOpt_t::pathlen, Reorder(), size, x509ChainVerifyOpt_t::when, and X509ChainError().

Referenced by XrdCryptoX509Chain(), CheckCA(), main(), and XrdCryptogsiX509Chain::Verify().

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

◆ X509ChainError()

const char * XrdCryptoX509Chain::X509ChainError ( EX509ChainErr  e)

Definition at line 229 of file XrdCryptoX509Chain.cc.

230 {
231  // Return error string
232 
233  return X509ChainErrStr[e];
234 }
static const char * X509ChainErrStr[]

References X509ChainErrStr.

Referenced by CheckCA(), XrdCryptogsiX509Chain::Verify(), and Verify().

+ Here is the caller graph for this function:

Member Data Documentation

◆ begin

◆ cahash

XrdOucString XrdCryptoX509Chain::cahash
protected

◆ caname

XrdOucString XrdCryptoX509Chain::caname
protected

◆ current

XrdCryptoX509ChainNode* XrdCryptoX509Chain::current
protected

Definition at line 148 of file XrdCryptoX509Chain.hh.

Referenced by XrdCryptoX509Chain(), Begin(), Cleanup(), Next(), and Remove().

◆ eechash

XrdOucString XrdCryptoX509Chain::eechash
protected

Definition at line 157 of file XrdCryptoX509Chain.hh.

Referenced by XrdCryptoX509Chain(), Cleanup(), EEChash(), and Reorder().

◆ eecname

XrdOucString XrdCryptoX509Chain::eecname
protected

Definition at line 155 of file XrdCryptoX509Chain.hh.

Referenced by XrdCryptoX509Chain(), Cleanup(), EECname(), and Reorder().

◆ effca

XrdCryptoX509ChainNode* XrdCryptoX509Chain::effca
protected

Definition at line 151 of file XrdCryptoX509Chain.hh.

Referenced by XrdCryptoX509Chain(), Cleanup(), EffCA(), and SetEffectiveCA().

◆ end

XrdCryptoX509ChainNode* XrdCryptoX509Chain::end
protected

◆ lastError

XrdOucString XrdCryptoX509Chain::lastError
protected

◆ previous

XrdCryptoX509ChainNode* XrdCryptoX509Chain::previous
protected

Definition at line 150 of file XrdCryptoX509Chain.hh.

Referenced by XrdCryptoX509Chain(), Begin(), Cleanup(), Next(), and Remove().

◆ size

int XrdCryptoX509Chain::size
protected

◆ statusCA

ECAStatus XrdCryptoX509Chain::statusCA
protected

The documentation for this class was generated from the following files: