00001
00002
00003 const char *XrdCryptosslgsiX509ChainCVSID = "$Id: XrdCryptosslgsiX509Chain.cc 30949 2009-11-02 16:37:58Z ganis $";
00004
00005
00006
00007
00008
00009
00010
00011 #include <string.h>
00012 #include <time.h>
00013
00014 #include <XrdCrypto/XrdCryptosslgsiAux.hh>
00015 #include <XrdCrypto/XrdCryptosslgsiX509Chain.hh>
00016 #include <XrdCrypto/XrdCryptoTrace.hh>
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 bool XrdCryptosslgsiX509Chain::Verify(EX509ChainErr &errcode, x509ChainVerifyOpt_t *vopt)
00028 {
00029
00030 EPNAME("X509Chain::Verify");
00031 errcode = kNone;
00032
00033
00034 if (size < 2) {
00035 DEBUG("Nothing to verify (size: "<<size<<")");
00036 return 0;
00037 }
00038 if (QTRACE(Dump)) { Dump(); }
00039
00040
00041
00042 if (Reorder() != 0) {
00043 errcode = kInconsistent;
00044 lastError = ":";
00045 lastError += X509ChainError(errcode);
00046 return 0;
00047 }
00048
00049
00050
00051 int opt = (vopt) ? vopt->opt : 0;
00052 int when = (vopt) ? vopt->when : (int)time(0);
00053 int plen = (vopt) ? vopt->pathlen : -1;
00054 XrdCryptoX509Crl *crl = (vopt) ? vopt->crl : 0;
00055
00056
00057
00058 if (plen > -1 && plen < size) {
00059 errcode = kTooMany;
00060 lastError = "checking path depth: ";
00061 lastError += X509ChainError(errcode);
00062 }
00063
00064
00065
00066
00067 XrdCryptoX509ChainNode *node = begin;
00068 XrdCryptoX509 *xcer = node->Cert();
00069 XrdCryptoX509 *xsig = xcer;
00070 if (statusCA == kUnknown) {
00071 if (!XrdCryptoX509Chain::Verify(errcode, "CA: ",
00072 XrdCryptoX509::kCA, when, xcer, xsig))
00073 return 0;
00074 statusCA = kValid;
00075 } else if (statusCA == kAbsent || statusCA == kInvalid) {
00076 errcode = kNoCA;
00077 lastError = X509ChainError(errcode);
00078 return 0;
00079 }
00080
00081
00082
00083 if (plen > -1)
00084 plen -= 1;
00085
00086
00087 while (node->Next() && strcmp(node->Next()->Cert()->Type(), "Proxy")) {
00088 xsig = xcer;
00089 node = node->Next();
00090 xcer = node->Cert();
00091 if (!XrdCryptoX509Chain::Verify(errcode, "EEC or sub-CA: ",
00092 XrdCryptoX509::kUnknown,
00093 when, xcer, xsig, crl))
00094 return 0;
00095
00096
00097 if (plen > -1)
00098 plen -= 1;
00099 }
00100
00101
00102
00103 xsig = xcer;
00104 node = node->Next();
00105 while (node && (plen == -1 || plen > 0)) {
00106
00107
00108 xcer = node->Cert();
00109
00110
00111 if (!SubjectOK(errcode, xcer))
00112 return 0;
00113
00114
00115 int pxplen = -1;
00116 if (opt & kOptsRfc3820) {
00117 const void *extdata = xcer->GetExtension(gsiProxyCertInfo_OID);
00118 if (!extdata || !XrdSslgsiProxyCertInfo(extdata, pxplen)) {
00119 errcode = kMissingExtension;
00120 lastError = "rfc3820: ";
00121 lastError += X509ChainError(errcode);
00122 return 0;
00123 }
00124 }
00125
00126 if (plen == -1) {
00127 plen = (pxplen > -1) ? pxplen : plen;
00128 } else {
00129 plen--;
00130
00131 plen = (pxplen > -1 && pxplen < plen) ? pxplen : plen;
00132 }
00133
00134
00135 if (!XrdCryptoX509Chain::Verify(errcode, "Proxy: ",
00136 XrdCryptoX509::kProxy, when, xcer, xsig))
00137 return 0;
00138
00139
00140 xsig = xcer;
00141 node = node->Next();
00142 }
00143
00144
00145 return 1;
00146 }
00147
00148
00149
00150 bool XrdCryptosslgsiX509Chain::SubjectOK(EX509ChainErr &errcode, XrdCryptoX509 *xcer)
00151 {
00152
00153
00154
00155 if (!xcer) {
00156 errcode = kNoCertificate;
00157 lastError = "subject check:";
00158 lastError += X509ChainError(errcode);
00159 return 0;
00160 }
00161
00162
00163 if (xcer->type != XrdCryptoX509::kProxy)
00164 return 1;
00165
00166
00167 if (!(xcer->Subject()) || !(xcer->Issuer())) {
00168 errcode = kInvalidNames;
00169 lastError = "subject check:";
00170 lastError += X509ChainError(errcode);
00171 return 0;
00172 }
00173
00174
00175
00176
00177
00178
00179
00180 int ilen = strlen(xcer->Issuer());
00181 if (strncmp(xcer->Subject(), xcer->Issuer(), ilen)) {
00182
00183 char *pcn = (char *) strstr(xcer->Issuer(), "/CN=");
00184 if (pcn) {
00185 char *pcnn = 0;
00186 while ((pcnn = (char *) strstr(pcn+1,"/CN=")))
00187 pcn = pcnn;
00188 ilen = (int)(pcn - xcer->Issuer());
00189 }
00190 if (strncmp(xcer->Subject() + ilen,"/CN=",4)) {
00191 errcode = kInvalidNames;
00192 lastError = "proxy subject check: found additional chars :";
00193 lastError += X509ChainError(errcode);
00194 return 0;
00195 }
00196 if (strncmp(xcer->Subject(), xcer->Issuer(), ilen)) {
00197 errcode = kInvalidNames;
00198 lastError = "proxy issuer check: issuer not found in subject :";
00199 lastError += X509ChainError(errcode);
00200 return 0;
00201 }
00202 }
00203
00204
00205 char *pp = (char *)strstr(xcer->Subject()+ilen, "CN=");
00206 if (!pp) {
00207 errcode = kInvalidNames;
00208 lastError = "proxy subject check: no appended 'CN='";
00209 lastError += X509ChainError(errcode);
00210 return 0;
00211 }
00212
00213
00214 pp = strstr(pp+strlen("CN="), "CN=");
00215 if (pp) {
00216 errcode = kInvalidNames;
00217 lastError = "proxy subject check: too many appended 'CN='s";
00218 lastError += X509ChainError(errcode);
00219 return 0;
00220 }
00221
00222
00223 return 1;
00224 }
00225
00226