XrdCryptoX509Chain.cc

Go to the documentation of this file.
00001 // $Id: XrdCryptoX509Chain.cc 33678 2010-06-01 08:19:53Z ganis $
00002 
00003 const char *XrdCryptoX509ChainCVSID = "$Id: XrdCryptoX509Chain.cc 33678 2010-06-01 08:19:53Z ganis $";
00004 /******************************************************************************/
00005 /*                                                                            */
00006 /*                  X r d C r y p t o X 5 0 9 C h a i n . c c                 */
00007 /*                                                                            */
00008 /* (c) 2005  G. Ganis, CERN                                                   */
00009 /*                                                                            */
00010 /******************************************************************************/
00011 #include <time.h>
00012 #include <string.h>
00013 
00014 #include <XrdCrypto/XrdCryptoX509Chain.hh>
00015 #include <XrdCrypto/XrdCryptoTrace.hh>
00016 
00017 
00018 // ---------------------------------------------------------------------------//
00019 //                                                                            //
00020 // XrdCryptoX509Chain                                                         //
00021 //                                                                            //
00022 // Light single-linked list for managing stacks of XrdCryptoX509* objects     //
00023 //                                                                            //
00024 // ---------------------------------------------------------------------------//
00025 
00026 // For test dumps, to avoid interfering with the trace mutex
00027 #define LOCDUMP(y)    { cerr << epname << ":" << y << endl; }
00028 
00029 // Description of errors
00030 static const char *X509ChainErrStr[] = {
00031    "no error condition occured",         // 0
00032    "chain is inconsistent",              // 1
00033    "size exceeds max allowed depth",     // 2
00034    "invalid or missing CA",              // 3
00035    "certificate missing",                // 4
00036    "unexpected certificate type",        // 5
00037    "names invalid or missing",           // 6
00038    "certificate has been revoked",       // 7
00039    "certificate expired",                // 8
00040    "extension not found",                // 9
00041    "signature verification failed",      // 10
00042    "issuer had no signing rights",       // 11
00043    "CA issued by another CA"             // 12
00044 };
00045 
00046 //___________________________________________________________________________
00047 XrdCryptoX509Chain::XrdCryptoX509Chain(XrdCryptoX509 *c)
00048 {
00049    // Constructor
00050 
00051    previous = 0;
00052    current = 0;
00053    begin = 0;
00054    end = 0;
00055    size = 0; 
00056    lastError = "";
00057    caname = "";
00058    eecname = "";
00059    cahash = "";
00060    eechash = "";
00061    statusCA = kUnknown;
00062 
00063    if (c) {
00064       XrdCryptoX509ChainNode *f = new XrdCryptoX509ChainNode(c,0);
00065       current = begin = end = f;
00066       size++;
00067       //
00068       // If CA verify it and save result
00069       if (c->type == XrdCryptoX509::kCA) {
00070          caname = c->Subject();
00071          cahash = c->SubjectHash();
00072          EX509ChainErr ecode = kNone;
00073          if (!Verify(ecode, "CA: ",XrdCryptoX509::kCA, 0, c, c))
00074             statusCA = kInvalid;
00075          else
00076             statusCA = kValid;
00077       }
00078    }
00079 } 
00080 
00081 //___________________________________________________________________________
00082 XrdCryptoX509Chain::XrdCryptoX509Chain(XrdCryptoX509Chain *ch)
00083 {
00084    // Copy constructor
00085 
00086    previous = 0;
00087    current = 0;
00088    begin = 0;
00089    end = 0;
00090    size = 0; 
00091    lastError = ch->LastError();
00092    caname = ch->CAname();
00093    eecname = ch->EECname();
00094    cahash = ch->CAhash();
00095    eechash = ch->EEChash();
00096    statusCA = ch->StatusCA(); 
00097 
00098    XrdCryptoX509 *c = ch->Begin();
00099    while (c) {
00100       XrdCryptoX509ChainNode *nc = new XrdCryptoX509ChainNode(c,0);
00101       if (!begin)
00102          begin = nc;
00103       if (end)
00104          end->SetNext(nc);
00105       end = nc;
00106       size++;
00107       // Go to Next
00108       c = ch->Next();
00109    }
00110 }
00111 
00112 //___________________________________________________________________________
00113 XrdCryptoX509Chain::~XrdCryptoX509Chain()
00114 {
00115    // Destructor
00116 
00117    XrdCryptoX509ChainNode *n = 0;
00118    XrdCryptoX509ChainNode *c = begin;
00119    while (c) {
00120       n = c->Next();
00121       delete (c);
00122       c = n;
00123    }
00124 }
00125 
00126 //___________________________________________________________________________
00127 void XrdCryptoX509Chain::Cleanup(bool keepCA)
00128 {
00129    // Destructs content of nodes AND their content
00130    // If keepCA is true, the top CA is kept
00131 
00132    XrdCryptoX509ChainNode *n = 0;
00133    XrdCryptoX509ChainNode *c = begin;
00134    while (c) {
00135       n = c->Next();
00136       if (c->Cert() &&
00137          (!keepCA || (c->Cert()->type != XrdCryptoX509::kCA)))
00138          delete (c->Cert());
00139       delete (c);
00140       c = n;
00141    }
00142 
00143    // Reset
00144    previous = 0;
00145    current = 0;
00146    begin = 0;
00147    end = 0;
00148    size = 0; 
00149    lastError = "";
00150    caname = "";
00151    eecname = "";
00152    cahash = "";
00153    eechash = "";
00154    statusCA = kUnknown;
00155 }
00156 
00157 //___________________________________________________________________________
00158 bool XrdCryptoX509Chain::CheckCA(bool checkselfsigned)
00159 {
00160    // Search the list for a valid CA and set it at top.
00161    // Search stops when a valid CA is found; an invalid CA is flagged.
00162    // A second CA is always ignored.
00163    // Signature check failures are accepted if 'checkselfsigned' is false.
00164    // Return 1 if found, 0 otherwise; lastError is filled with the reason of
00165    // failure, if any.
00166 
00167    XrdCryptoX509 *xc = 0;
00168    XrdCryptoX509ChainNode *n = 0;
00169    XrdCryptoX509ChainNode *c = begin;
00170    XrdCryptoX509ChainNode *p = 0;
00171    lastError = "";
00172    while (c) {
00173       n = c->Next();
00174       xc = c->Cert();
00175       if (xc && xc->type == XrdCryptoX509::kCA) {
00176          caname = xc->Subject();
00177          cahash = xc->SubjectHash();
00178          EX509ChainErr ecode = kNone;
00179          bool CAok = Verify(ecode, "CA: ",XrdCryptoX509::kCA, 0, xc, xc);
00180          if (!CAok && (ecode != kVerifyFail || checkselfsigned)) {
00181             statusCA = kInvalid;
00182             lastError += X509ChainError(ecode);
00183          } else {
00184             statusCA = kValid;
00185             if (p) {
00186                // Move at top
00187                p->SetNext(c->Next());
00188                c->SetNext(begin);
00189                if (end == c) end = p;
00190                begin = c;
00191             }
00192             return 1;
00193          }
00194       }
00195       p = c;  // Previous node
00196       c = n;
00197    }
00198 
00199    // Found nothing
00200    return 0;
00201 }
00202 
00203 //___________________________________________________________________________
00204 const char *XrdCryptoX509Chain::X509ChainError(EX509ChainErr e)
00205 {
00206    // Return error string
00207 
00208    return X509ChainErrStr[e];
00209 }
00210 
00211 //___________________________________________________________________________
00212 XrdCryptoX509ChainNode *XrdCryptoX509Chain::Find(XrdCryptoX509 *c)
00213 {
00214    // Find node containing bucket b
00215 
00216    XrdCryptoX509ChainNode *nd = begin;
00217    for (; nd; nd = nd->Next()) {
00218       if (nd->Cert() == c)
00219          return nd;
00220    }
00221    return (XrdCryptoX509ChainNode *)0;
00222 }
00223 
00224 //___________________________________________________________________________
00225 void XrdCryptoX509Chain::PutInFront(XrdCryptoX509 *c)
00226 {
00227    // Add at the beginning of the list
00228    // Check to avoid duplicates
00229 
00230    if (!Find(c)) {
00231       XrdCryptoX509ChainNode *nc = new XrdCryptoX509ChainNode(c,begin);
00232       begin = nc;
00233       if (!end)
00234          end = nc;
00235       size++;
00236    }
00237 }
00238 
00239 //___________________________________________________________________________
00240 void XrdCryptoX509Chain::InsertAfter(XrdCryptoX509 *c, XrdCryptoX509 *cp)
00241 {
00242    // Add or move certificate 'c' after certificate 'cp'; if 'cp' is not
00243    // in the list, push-back
00244 
00245    XrdCryptoX509ChainNode *nc = Find(c);
00246    XrdCryptoX509ChainNode *ncp = Find(cp);
00247    if (ncp) {
00248       // Create a new node, if not there
00249       if (!nc) {
00250          nc = new XrdCryptoX509ChainNode(c,ncp->Next());
00251          size++;
00252       }
00253       // Update pointers
00254       ncp->SetNext(nc);
00255       if (end == ncp)
00256          end = nc;
00257 
00258    } else {
00259       // Referebce certificate not in the list
00260       // If new, add in last position; otherwise leave it where it is
00261       if (!nc)
00262          PushBack(c);
00263    }
00264 }
00265 
00266 //___________________________________________________________________________
00267 void XrdCryptoX509Chain::PushBack(XrdCryptoX509 *c)
00268 {
00269    // Add at the end of the list
00270    // Check to avoid duplicates
00271 
00272    if (!Find(c)) {
00273       XrdCryptoX509ChainNode *nc = new XrdCryptoX509ChainNode(c,0);
00274       if (!begin)
00275          begin = nc;
00276       if (end)
00277          end->SetNext(nc);
00278       end = nc;
00279       size++;
00280    }
00281 }
00282 
00283 //___________________________________________________________________________
00284 void XrdCryptoX509Chain::Remove(XrdCryptoX509 *c)
00285 {
00286    // Remove node containing bucket b
00287 
00288    XrdCryptoX509ChainNode *curr = current;
00289    XrdCryptoX509ChainNode *prev = previous;
00290 
00291    if (!curr || curr->Cert() != c || (prev && curr != prev->Next())) {
00292       // We need first to find the address
00293       curr = begin;
00294       prev = 0;
00295       for (; curr; curr = curr->Next()) {
00296          if (curr->Cert() == c)
00297             break;
00298          prev = curr;
00299       }
00300    }
00301 
00302    // The certificate is not in the list
00303    if (!curr)
00304       return;
00305 
00306    //
00307    // If this was the top CA update the related information
00308    if (c->type == XrdCryptoX509::kCA && curr == begin) {
00309       // There may be other CAs in the chain, but we will
00310       // check when needed
00311       statusCA = kUnknown;
00312       caname = "";
00313       cahash = "";
00314    }
00315 
00316    // Now we have all the information to remove
00317    if (prev) {
00318       current  = curr->Next();
00319       prev->SetNext(current);
00320       previous = curr;
00321    } else if (curr == begin) {
00322       // First buffer
00323       current  = curr->Next();
00324       begin = current;
00325       previous = 0;
00326    }
00327 
00328    // Cleanup and update size
00329    delete curr;
00330    size--;
00331 }
00332 
00333 //___________________________________________________________________________
00334 XrdCryptoX509 *XrdCryptoX509Chain::Begin()
00335 { 
00336    // Iterator functionality: init
00337 
00338    previous = 0;
00339    current = begin;
00340    if (current)
00341       return current->Cert();
00342    return (XrdCryptoX509 *)0;
00343 }
00344 
00345 //___________________________________________________________________________
00346 XrdCryptoX509 *XrdCryptoX509Chain::Next()
00347 { 
00348    // Iterator functionality: get next
00349 
00350    previous = current;
00351    if (current) {
00352       current = current->Next();
00353       if (current)
00354          return current->Cert();
00355    }
00356    return (XrdCryptoX509 *)0;
00357 }
00358 
00359 //___________________________________________________________________________
00360 XrdCryptoX509 *XrdCryptoX509Chain::SearchByIssuer(const char *issuer,
00361                                                   ESearchMode mode)
00362 { 
00363    // Return first certificate in the chain with issuer
00364    // Match according to mode.
00365 
00366    XrdCryptoX509ChainNode *cn = FindIssuer(issuer, mode);
00367 
00368    // We are done
00369    return ((cn) ? cn->Cert() : (XrdCryptoX509 *)0);
00370 }
00371 
00372 //___________________________________________________________________________
00373 XrdCryptoX509 *XrdCryptoX509Chain::SearchBySubject(const char *subject,
00374                                                    ESearchMode mode)
00375 { 
00376    // Return first certificate in the chain with subject
00377    // Match according to mode.
00378 
00379    XrdCryptoX509ChainNode *cn = FindSubject(subject, mode);
00380 
00381    // We are done
00382    return ((cn) ? cn->Cert() : (XrdCryptoX509 *)0);
00383 
00384 }
00385 
00386 //___________________________________________________________________________
00387 XrdCryptoX509ChainNode *XrdCryptoX509Chain::FindIssuer(const char *issuer,
00388                           ESearchMode mode, XrdCryptoX509ChainNode **prev)
00389 { 
00390    // Return first chain node with certificate having issuer
00391    // Match according to mode.
00392 
00393    // Make sure we got something to compare
00394    if (!issuer) 
00395       return (XrdCryptoX509ChainNode *)0;
00396 
00397    XrdCryptoX509ChainNode *cp = 0;
00398    XrdCryptoX509ChainNode *n = 0;
00399    XrdCryptoX509ChainNode *cn = begin;
00400    XrdCryptoX509 *c = 0;
00401    while (cn) {
00402       n = cn->Next();
00403       c = cn->Cert();
00404       const char *pi = c->Issuer();
00405       if (c && pi) {
00406          if (mode == kExact) {
00407             if (!strcmp(pi, issuer))
00408                break;
00409          } else if (mode == kBegin) {
00410             if (strstr(pi, issuer) == c->Issuer())
00411                break;
00412          } else if (mode == kEnd) {
00413             int ibeg = strlen(pi) - strlen(issuer);
00414             if (!strcmp(pi + ibeg, issuer))
00415                break;
00416          }
00417       }
00418       c = 0;
00419       cp = cn;  // previous
00420       cn = n;
00421    }
00422    // return previous, if requested
00423    if (prev)
00424       *prev = (cn) ? cp : 0;
00425 
00426    // We are done
00427    return ((cn) ? cn : (XrdCryptoX509ChainNode *)0);
00428 }
00429 
00430 //___________________________________________________________________________
00431 XrdCryptoX509ChainNode *XrdCryptoX509Chain::FindSubject(const char *subject,
00432                             ESearchMode mode, XrdCryptoX509ChainNode **prev)
00433 { 
00434    // Return first chain node with certificate having subject
00435    // Match according to mode.
00436 
00437    // Make sure we got something to compare
00438    if (!subject) 
00439       return (XrdCryptoX509ChainNode *)0;
00440 
00441    XrdCryptoX509ChainNode *cp = 0;
00442    XrdCryptoX509ChainNode *n = 0;
00443    XrdCryptoX509ChainNode *cn = begin;
00444    XrdCryptoX509 *c = 0;
00445    while (cn) {
00446       n = cn->Next();
00447       c = cn->Cert();
00448       const char *ps = c ? c->Subject() : 0;
00449       if (c && ps) {
00450          if (mode == kExact) {
00451             if (!strcmp(ps, subject))
00452                break;
00453          } else if (mode == kBegin) {
00454             if (strstr(ps, subject) == ps)
00455                break;
00456          } else if (mode == kEnd) {
00457             int sbeg = strlen(ps) - strlen(subject);
00458             if (!strcmp(ps + sbeg, subject))
00459                break;
00460          }
00461       }
00462       c = 0;
00463       cp = cn;  // previous
00464       cn = n;
00465    }
00466    // return previous, if requested
00467    if (prev)
00468       *prev = (cn) ? cp : 0;
00469 
00470    // We are done
00471    return ((cn) ? cn : (XrdCryptoX509ChainNode *)0);
00472 }
00473 
00474 //___________________________________________________________________________
00475 void XrdCryptoX509Chain::Dump()
00476 {
00477    // Dump content
00478    EPNAME("X509Chain::Dump");
00479 
00480    LOCDUMP("//------------------Dumping X509 chain content ------------------//");
00481    LOCDUMP("//");
00482    LOCDUMP("// Chain instance: "<<this);
00483    LOCDUMP("//");
00484    LOCDUMP("// Number of certificates: "<<Size());
00485    LOCDUMP("//");
00486    if (CAname()) {
00487       LOCDUMP("// CA:  "<<CAname());
00488    } else {
00489       LOCDUMP("// CA: absent");
00490    }
00491    if (EECname()) {
00492       LOCDUMP("// EEC:  "<<EECname());
00493    } else {
00494       LOCDUMP("// EEC: absent");
00495    }
00496    LOCDUMP("//");
00497    XrdCryptoX509ChainNode *n = 0;
00498    XrdCryptoX509ChainNode *c = begin;
00499    while (c) {
00500       n = c->Next();
00501       if (c->Cert()) {
00502          LOCDUMP("// Issuer: "<<c->Cert()->IssuerHash()<<
00503                " Subject: "<<c->Cert()->SubjectHash()<<
00504                   " Type: "<<c->Cert()->Type());
00505       }
00506       c = n;
00507    }
00508    LOCDUMP("//");
00509    LOCDUMP("//---------------------------- END ------------------------------//")
00510 }
00511 
00512 //___________________________________________________________________________
00513 int XrdCryptoX509Chain::Reorder()
00514 { 
00515    // Reorder certificates in such a way that certificate n is the
00516    // issuer of certificate n+1 .
00517    // Return -1 if inconsistencies are found.
00518    EPNAME("X509Chain::Reorder");
00519 
00520    if (size < 2) {
00521       DEBUG("Nothing to reorder (size: "<<size<<")");
00522       return 0;
00523    }
00524 
00525    // Loop over the certificates
00526    XrdCryptoX509ChainNode *nc = 0, *np = 0, *nn = 0, *nr = 0, *npp = 0;
00527 
00528    // Look for the first one, if needed
00529    nr = begin;
00530    np = nr;
00531    while (nr) {
00532       //
00533       if (!(nn = FindSubject(nr->Cert()->Issuer(),kExact,&npp)) ||
00534             nn == nr)
00535          break;
00536       np = nr;
00537       nr = nr->Next();
00538    }
00539 
00540    // Move it in first position if not yet there
00541    if (nr != begin) { 
00542       np->SetNext(nr->Next()); // short cut old position
00543       nr->SetNext(begin);      // set our next to present begin
00544       if (end == nr)           // Update end
00545          end = np;
00546       begin = nr;              // set us as begin
00547       // Flag if not CA: we do not check validity here
00548       if (nr->Cert()->type != XrdCryptoX509::kCA) {
00549          statusCA = kAbsent;
00550       } else if (caname.length() <= 0) {
00551          // Set the CA properties only if not done already to avoid overwriting
00552          // the result of previous analysis
00553          caname = nr->Cert()->Subject();
00554          cahash = nr->Cert()->SubjectHash();
00555          statusCA = kUnknown;
00556       }
00557    }
00558 
00559    int left = size-1;
00560    np = begin;
00561    while (np) {
00562       if (np->Cert()) {
00563          const char *pi = np->Cert()->Subject();
00564          // Set the EEC name, if not yet done
00565          if (np->Cert()->type == XrdCryptoX509::kEEC && eecname.length() <= 0) {
00566             eecname = pi;
00567             eechash = np->Cert()->SubjectHash();
00568          }
00569          npp = np;
00570          nc = np->Next();
00571          while (nc) {
00572             if (nc->Cert() && !strcmp(pi, nc->Cert()->Issuer())) {
00573                left--;
00574                if (npp != np) {
00575                   npp->SetNext(nc->Next()); // drop child from previous pos
00576                   nc->SetNext(np->Next());  // set child next as our present
00577                   np->SetNext(nc);          // set our next as child
00578                   if (nc == end)
00579                      end = npp;
00580                }
00581                break;
00582             }
00583             npp = nc;
00584             nc = nc->Next();
00585          }
00586       }
00587       np = np->Next();
00588    }
00589 
00590    // Check consistency
00591    if (left > 0) {
00592       DEBUG("Inconsistency found: "<<left<<
00593             " certificates could not be correctly enchained!");
00594       return -1;
00595    }
00596 
00597    // We are done
00598    return 0;
00599 } 
00600 
00601 //___________________________________________________________________________
00602 bool XrdCryptoX509Chain::Verify(EX509ChainErr &errcode, x509ChainVerifyOpt_t *vopt)
00603 {
00604    // Verify cross signatures of the chain
00605    EPNAME("X509Chain::Verify");
00606    errcode = kNone; 
00607 
00608    // Do nothing if empty 
00609    if (size < 1) {
00610       DEBUG("Nothing to verify (size: "<<size<<")");
00611       return 0;
00612    }
00613 
00614    //
00615    // Reorder if needed
00616    if (Reorder() != 0) {
00617       errcode = kInconsistent;
00618       lastError = ":";
00619       lastError += X509ChainError(errcode);
00620       return 0;
00621    }
00622 
00623    //
00624    // Verification options
00625    int when = (vopt) ? vopt->when : (int)time(0);
00626    int plen = (vopt) ? vopt->pathlen : -1;
00627    bool chkss = (vopt) ? (vopt->opt & kOptsCheckSelfSigned) : 1;
00628 
00629    //
00630    // Global path depth length consistency check
00631    if (plen > -1 && plen < size) {
00632       errcode = kTooMany;
00633       lastError = "checking path depth: ";
00634       lastError += X509ChainError(errcode);
00635    }
00636 
00637    //
00638    // Check the first certificate: it MUST be of CA type, valid,
00639    // self-signed
00640    if (!CheckCA(chkss)) {
00641       errcode = kNoCA;
00642       lastError = X509ChainError(errcode);
00643       return 0;
00644    }
00645 
00646    //
00647    // Analyse the rest
00648    XrdCryptoX509ChainNode *node = begin;
00649    XrdCryptoX509 *xsig = node->Cert();    // Signing certificate
00650    XrdCryptoX509 *xcer = 0;               // Certificate under exam
00651    node = node->Next();
00652    while (node) {
00653 
00654       // Attache to certificate
00655       xcer = node->Cert();
00656 
00657       // Standard verification
00658       if (!Verify(errcode, "cert: ", XrdCryptoX509::kUnknown, when, xcer, xsig))
00659          return 0;
00660 
00661       // Get next
00662       xsig = xcer;
00663       node = node->Next();
00664    }
00665 
00666    // We are done (successfully!)
00667    return 1;
00668 }
00669 
00670 //___________________________________________________________________________
00671 int XrdCryptoX509Chain::CheckValidity(bool outatfirst, int when)
00672 {
00673    // Check validity at 'when' of certificates in the chain and return
00674    // the number of invalid certificates.
00675    // If 'outatfirst' return after the first invalid has been
00676    // found.
00677    EPNAME("X509Chain::CheckValidity");
00678    int ninv = 0;
00679 
00680    // Do nothing if empty 
00681    if (size < 1) {
00682       DEBUG("Nothing to verify (size: "<<size<<")");
00683       return ninv;
00684    }
00685 
00686    // Loop over the certificates
00687    XrdCryptoX509ChainNode *nc = begin;
00688    while (nc) {
00689       //
00690       XrdCryptoX509 *c = nc->Cert();
00691       if (c) {
00692          if (!(c->IsValid(when))) {
00693             ninv++;
00694             DEBUG("invalid certificate found");
00695             if (outatfirst)
00696                return ninv;
00697          }
00698       } else {
00699          ninv++;
00700          DEBUG("found node without certificate");
00701          if (outatfirst)
00702             return ninv;
00703       }
00704       // Get next      
00705       nc = nc->Next();
00706    }
00707 
00708    // We are done
00709    return ninv;
00710 }
00711 
00712 //___________________________________________________________________________
00713 bool XrdCryptoX509Chain::Verify(EX509ChainErr &errcode, const char *msg,
00714                                 XrdCryptoX509::EX509Type type, int when,
00715                                 XrdCryptoX509 *xcer, XrdCryptoX509 *xsig,
00716                                 XrdCryptoX509Crl *crl)
00717 {
00718    // Internal verification method
00719 
00720    // Certificate must be defined
00721    if (!xcer) {
00722       errcode = kNoCertificate;
00723       lastError = msg;
00724       lastError += X509ChainError(errcode);
00725       return 0;
00726    }
00727 
00728    // Type should be the one expected
00729    if (type != XrdCryptoX509::kUnknown && xcer->type != type) {
00730       errcode = kInvalidType;
00731       lastError = msg;
00732       lastError += X509ChainError(errcode);
00733       return 0;
00734    }
00735 
00736    // Must not be revoked (check only if required)
00737    if (crl) {
00738       // Get certificate serial number
00739       XrdOucString sn = xcer->SerialNumberString();
00740       if (crl->IsRevoked(sn.c_str(), when)) {
00741          errcode = kRevoked;
00742          lastError = msg;
00743          lastError += X509ChainError(errcode);
00744          return 0;
00745       }
00746    }
00747 
00748    // Check validity in time
00749    if (when >= 0 && !(xcer->IsValid(when))) {
00750       errcode = kExpired;
00751       lastError = msg;
00752       lastError += X509ChainError(errcode);
00753       return 0;
00754    }
00755 
00756    // Check signature
00757    if (!xsig || !(xcer->Verify(xsig))) {
00758       errcode = kVerifyFail;
00759       lastError = msg;
00760       lastError += X509ChainError(errcode);
00761       return 0;
00762    }
00763 
00764    // We are done
00765    return 1;
00766 }
00767 
00768 //_____________________________________________________________________________
00769 const char *XrdCryptoX509Chain::CAname()
00770 {
00771    // Return subject name of the CA in the chain
00772    EPNAME("X509Chain::CAname");
00773 
00774    // If we do not have it already, try extraction
00775    if (caname.length() <= 0 && statusCA == kUnknown) {
00776 
00777       if (!CheckCA()) {
00778          DEBUG("CA not found in chain");
00779          return (const char *)0;
00780       }
00781    }
00782 
00783    // return what we have
00784    return (caname.length() > 0) ? caname.c_str() : (const char *)0;
00785 }
00786 
00787 //_____________________________________________________________________________
00788 const char *XrdCryptoX509Chain::EECname()
00789 {
00790    // Return subject name of the EEC in the chain
00791    EPNAME("X509Chain::EECname");
00792 
00793    // If we do not have it already, try extraction
00794    if (eecname.length() <= 0) {
00795 
00796       XrdCryptoX509ChainNode *c = begin;
00797       while (c) {
00798          if (c->Cert()->type == XrdCryptoX509::kEEC) {
00799             eecname = c->Cert()->Subject();
00800             break;
00801          }
00802          c = c->Next();
00803       }
00804       if (eecname.length() <= 0) {
00805          DEBUG("EEC not found in chain");
00806          return (const char *)0;
00807       }
00808    }
00809 
00810    // return what we have
00811    return (eecname.length() > 0) ? eecname.c_str() : (const char *)0;
00812 }
00813 
00814 //_____________________________________________________________________________
00815 const char *XrdCryptoX509Chain::CAhash()
00816 {
00817    // Return the subject name hash of the CA in the chain
00818    EPNAME("X509Chain::CAhash");
00819 
00820    // If we do not have it already, try extraction
00821    if (cahash.length() <= 0 && statusCA == kUnknown) {
00822 
00823       if (!CheckCA()) {
00824          DEBUG("CA not found in chain");
00825          return (const char *)0;
00826       }
00827    }
00828 
00829    // return what we have
00830    return (cahash.length() > 0) ? cahash.c_str() : (const char *)0;
00831 }
00832 
00833 //_____________________________________________________________________________
00834 const char *XrdCryptoX509Chain::EEChash()
00835 {
00836    // Return the subject name hash of the EEC in the chain
00837    EPNAME("X509Chain::EEChash");
00838 
00839    // If we do not have it already, try extraction
00840    if (eechash.length() <= 0) {
00841 
00842       XrdCryptoX509ChainNode *c = begin;
00843       while (c) {
00844          if (c->Cert()->type == XrdCryptoX509::kEEC) {
00845             eechash = c->Cert()->SubjectHash();
00846             break;
00847          }
00848          c = c->Next();
00849       }
00850       if (eechash.length() <= 0) {
00851          DEBUG("EEC not found in chain");
00852          return (const char *)0;
00853       }
00854    }
00855 
00856    // return what we have
00857    return (eechash.length() > 0) ? eechash.c_str() : (const char *)0;
00858 }

Generated on Tue Jul 5 14:46:34 2011 for ROOT_528-00b_version by  doxygen 1.5.1