XRootD
Loading...
Searching...
No Matches
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

◆ 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
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)

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()
const char * LastError() const
XrdCryptoX509 * Begin()
XrdCryptoX509 * EffCA() const
ECAStatus StatusCA() 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
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)
#define EPNAME(x)
bool CheckCA(bool checkselfsigned=1)
int length() const
const char * c_str() 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;
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)) {
207 lastError += X509ChainError(ecode);
208 } else {
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
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 = "";
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("//");
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
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
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
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)
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
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)
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)
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
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)
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)
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) {
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();
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)
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();
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, Verify(), x509ChainVerifyOpt_t::when, and X509ChainError().

Referenced by XrdCryptoX509Chain(), CheckCA(), main(), XrdCryptogsiX509Chain::Verify(), and 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(), Verify(), 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

◆ eechash

XrdOucString XrdCryptoX509Chain::eechash
protected

◆ eecname

XrdOucString XrdCryptoX509Chain::eecname
protected

◆ effca

XrdCryptoX509ChainNode* XrdCryptoX509Chain::effca
protected

◆ end

◆ lastError

XrdOucString XrdCryptoX509Chain::lastError
protected

◆ previous

XrdCryptoX509ChainNode* XrdCryptoX509Chain::previous
protected

◆ size

◆ statusCA


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