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 ()
 
XrdCryptoX509Begin ()
 
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 ()
 
XrdCryptoX509EffCA () const
 
XrdCryptoX509End () const
 
void InsertAfter (XrdCryptoX509 *c, XrdCryptoX509 *cp)
 
const char * LastError () const
 
XrdCryptoX509Next ()
 
void PushBack (XrdCryptoX509 *c)
 
void PutInFront (XrdCryptoX509 *c)
 
void Remove (XrdCryptoX509 *c)
 
virtual int Reorder ()
 
XrdCryptoX509SearchByIssuer (const char *issuer, ESearchMode mode=kExact)
 
XrdCryptoX509SearchBySubject (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

XrdCryptoX509ChainNodeFind (XrdCryptoX509 *c)
 
XrdCryptoX509ChainNodeFindIssuer (const char *issuer, ESearchMode mode=kExact, XrdCryptoX509ChainNode **p=0)
 
XrdCryptoX509ChainNodeFindSubject (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

XrdCryptoX509ChainNodebegin
 
XrdOucString cahash
 
XrdOucString caname
 
XrdCryptoX509ChainNodecurrent
 
XrdOucString eechash
 
XrdOucString eecname
 
XrdCryptoX509ChainNodeeffca
 
XrdCryptoX509ChainNodeend
 
XrdOucString lastError
 
XrdCryptoX509ChainNodeprevious
 
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: