PKIFScvpPathBuildAndValidate.cpp

Go to the documentation of this file.
00001 
00009 #include "PKIFScvpPathBuildAndValidate.h"
00010 #include "pkif.h"
00011 #include "PKIFSCVP.h"
00012 #include "private/SCVPUtils.h"
00013 #include "PKIFCMS.h"
00014 #include "PKIFERS.h"
00015 
00016 #include "IPKIFExtHandlerData.h"
00017 
00018 using namespace std;
00019 
00021 struct CPKIFScvpPathBuildAndValidateImpl
00022 {
00023 };
00025 
00033 CPKIFScvpPathBuildAndValidate::CPKIFScvpPathBuildAndValidate(void)
00034 {
00035 }
00036 
00044 CPKIFScvpPathBuildAndValidate::~CPKIFScvpPathBuildAndValidate(void)
00045 {
00046 }
00047 
00055 void CPKIFScvpPathBuildAndValidate::Initialize()
00056 {
00057 }
00058 
00066 bool CPKIFScvpPathBuildAndValidate::BuildAndValidatePath(
00068     CPKIFCertificatePath& path,
00070     CPKIFPathValidationResults& results)
00071 {
00072     CPKIFCertificatePtr targetCert;
00073     path.GetTarget(targetCert);
00074 
00075     if(!targetCert || !CheckNamespaces(targetCert))
00076         return false;
00077 
00078     CPKIFCVRequestPtr cvr(new CPKIFCVRequest);  
00079 
00080     CPKIFQueryPtr query = MakeQueryForPath(path, g_id_stc_build_status_checked_pkc_path, this);
00081 
00082     cvr->SetQuery(query);
00083     cvr->SetGenerateNonce(GetGenerateNonce());
00084 
00085     //declare variables that will be used to prepare a ContentInfo. 
00086     CPKIFBufferPtr contents = cvr->Encode();
00087     CPKIFOIDPtr contentType = g_id_ct_scvp_certValRequest;
00088 
00089     CPKIFCredentialPtr cred = GetSigningCredential();
00090     if(cred)
00091     {
00092         CPKIFSignedData sd;
00093         CPKIFEncapsulatedContentInfoPtr ecip(new CPKIFEncapsulatedContentInfo);
00094         ecip->SetOID(contentType);
00095         ecip->SetContent(contents);
00096 
00097         CPKIFSignerInfoPtr si(new CPKIFSignerInfo);
00098         si->SetCredential(cred);
00099 
00100         IPKIFScvpClient* thisAsScvpClient = dynamic_cast<IPKIFScvpClient*>(this);
00101 
00102         sd.SetEncapsulatedContent(ecip);
00103         IPKIFMediatorPtr tmpMed = thisAsScvpClient->GetMediator();
00104         sd.AddMediator(tmpMed);
00105         sd.AddSignerInfo(si);
00106         CPKIFCertificatePtr tmpCert = cred->GetCertificate();
00107         sd.AddCertificate(tmpCert);
00108 
00109         contents = sd.Encode();
00110 
00111         contentType = g_signedData;
00112     }
00113 
00114     CPKIFContentInfo ci;
00115     ci.SetContent(contents);
00116     ci.SetContentType(contentType);
00117 
00118     CPKIFBufferPtr encRequest = ci.Encode();
00119     CPKIFBufferPtr resp;
00120     const char* url = GetResponderUrl();
00121     if(PostRequestURL(encRequest, resp, url, PKIF_SCVP))
00122     {
00123         CPKIFCVResponsePtr parsedResponse;
00124 
00125         //VerifyResponseSignature parses the response, checks the status, checks the nonce (if necessary) 
00126         //and verifies the signature (if necessary)
00127         if(!VerifyResponseSignature(resp, this, cvr, false, parsedResponse))
00128         {
00129             //if everything checked by VerifyResponseSignature checks out, proceed by getting
00130             //the list of replyObjects
00131             CPKIFCertReplyListPtr replyObjects;
00132             parsedResponse->GetReplyObjects(replyObjects);
00133 
00134             //get the target cert from the path so we can find the correct reply object
00135             CPKIFCertificatePtr targetCert;
00136             path.GetTarget(targetCert);
00137             
00138             CPKIFCertReplyPtr replyObject = GetReplyObject(replyObjects, targetCert);
00139             if(replyObject)
00140             {
00141                 //we found a reply object, get its status.  this will determine what sort of processing is required
00142                 int replyStatus = replyObject->GetReplyStatus();
00143                 if(0 == replyStatus)
00144                 {
00145                     //sanity check the replyChecks and the valErrors.  the former should be all
00146                     //successful and the latter should be absent.
00147                     if(!MakeSureReplyChecksAreSuccessfulAndValErrorsAreAbsent(replyObject))
00148                         return false; //this response was busted, ignore it and let next colleague take a shot
00149 
00150                     //the response status indicates success
00151                     results.SetBasicChecksSuccessfullyPerformed(true);
00152                     results.SetCertSignaturesVerified(true);
00153                     results.SetRevocationStatusMostSevere(NOT_REVOKED);
00154                 }
00155                 else
00156                 {
00157                     results.SetBasicChecksSuccessfullyPerformed(false);
00158                     results.SetCertSignaturesVerified(false);
00159                     results.SetRevocationStatusMostSevere(NOT_CHECKED);
00160 
00161                     //need to step through the replyChecks
00162                     CPKIFReplyCheckListPtr replyChecks;
00163                     replyObject->GetReplyChecks(replyChecks);
00164 
00165                     if(replyChecks)
00166                     {
00167                         CPKIFReplyCheckList::iterator rcPos;
00168                         CPKIFReplyCheckList::iterator rcEnd = replyChecks->end();
00169                         for(rcPos = replyChecks->begin(); rcPos != rcEnd; ++rcPos)
00170                         {
00171                             CPKIFOIDPtr rcPosOid = (*rcPos)->GetCheck();
00172                             int rcPosStatus = (*rcPos)->GetStatus();
00173                             if(*g_id_stc_build_pkc_path == *rcPosOid)
00174                             {
00175                                 //expect the status to be 1, but don't need to do anything in this case
00176                             }
00177                             else if(*g_id_stc_build_valid_pkc_path == *rcPosOid)
00178                             {
00179                                 //expect the status to be 1, but don't need to do anything in this case
00180                             }
00181                             else if(*g_id_stc_build_status_checked_pkc_path == *rcPosOid)
00182                             {
00183                                 //if the status is greater than 1, then a valid path was found but the revocation
00184                                 //info was not available for one reason or another
00185                                 if(1 < rcPosStatus)
00186                                 {
00187                                     results.SetBasicChecksSuccessfullyPerformed(true);
00188                                     results.SetCertSignaturesVerified(true);
00189                                 }
00190                             }
00191                         }
00192                     }
00193 
00194                     //get validation errors (though without a wantBack we don't have anywhere good to put them)
00195                     CPKIFOIDListPtr valErrors;
00196                     replyObject->GetValErrors(valErrors);
00197                     if(valErrors)
00198                     {
00199                         CPKIFOIDList::iterator vePos;
00200                         CPKIFOIDList::iterator veEnd = valErrors->end();
00201                         for(vePos = valErrors->begin(); vePos != veEnd; ++vePos)
00202                         {                           
00203                             if(*g_id_bvae_expired == *vePos)
00204                             {
00205                             }
00206                             else if(*g_id_bvae_not_yet_valid == *vePos)
00207                             {
00208                             }
00209                             else if(*g_id_bvae_wrongTrustAnchor == *vePos)
00210                             {
00211                             }
00212                             else if(*g_id_bvae_noValidCertPath == *vePos)
00213                             {
00214                             }
00215                             else if(*g_id_bvae_revocked == *vePos)
00216                             {
00217                             }
00218                             else if(*g_id_bvae_invalidKeyPurpose == *vePos)
00219                             {
00220                             }
00221                             else if(*g_id_bvae_invalidKeyUsage == *vePos)
00222                             {
00223                             }
00224                             else if(*g_id_bvae_invalidKeyCertPolicy == *vePos)
00225                             {
00226                             }
00227                         }
00228                     }
00229                 }// else (corresponding to if(0 == replyStatus))
00230 
00231                 //collect information from the wantBacks (the spec indicates these will only be in 
00232                 //successful replies, but....
00233                 CPKIFReplyWantBackListPtr replyWantBackList;
00234                 replyObject->GetReplyWantBacks(replyWantBackList);
00235 
00236                 CPKIFReplyWantBack_ExtDataHandlerPtr emptyWantBacks;
00237                 SetWantBacksFromResponse(emptyWantBacks);
00238                 if(replyWantBackList)
00239                 {
00240                     //There are only two types of wantBacks that we support: best cert path and revocation info.
00241                     //The revocation info type needs to be processed first.  Thus, collect these two below and process
00242                     //them after both are in hand.
00243                     CPKIFBufferPtr bestCertPathWB, revInfoWB, partialPathWB;
00244                     CPKIFBufferPtr bestCertPathWB_ER, revInfoWB_ER, partialPathWB_ER, pkcCertWB_ER, ersAllWB_ER;                    
00245 
00246                     CPKIFReplyWantBack_ExtDataHandlerPtr edh(new CPKIFReplyWantBack_ExtDataHandler);
00247                     edh->m_scvpResponder = GetResponderUrl();
00248 
00249                     CPKIFReplyWantBackList::iterator pos;
00250                     CPKIFReplyWantBackList::iterator end = replyWantBackList->end();
00251                     for(pos = replyWantBackList->begin(); pos != end; ++pos)
00252                     {
00253                         std::pair<CPKIFReplyWantBackPtr, vector<SeqResultsPtr> > pair;
00254                         pair.first = *pos;
00255                         edh->m_wantBacks.push_back(pair);
00256 
00257                         CPKIFOIDPtr posOid = (*pos)->GetWB();
00258                         if(*g_id_swb_pkc_best_cert_path == *posOid)
00259                         {
00260                             bestCertPathWB = (*pos)->GetValue();
00261                         }
00262                         else if(*g_id_swb_pkc_revocation_info == *posOid)
00263                         {
00264                             revInfoWB = (*pos)->GetValue();
00265                         }
00266                         else if(*g_id_swb_pkc_public_key_info == *posOid)
00267                         {
00268                             //Not supported
00269                         }
00270                         else if(*g_id_swb_pkc_relayed_responses == *posOid)
00271                         {
00272                             //Not supported
00273                         }
00274                         else if(*g_id_swb_pkc_all_cert_paths == *posOid)
00275                         {
00276                             //Not supported
00277                         }
00278                         else if(*g_id_swb_pkc_ee_revocation_info == *posOid)
00279                         {
00280                             //Not supported
00281                         }
00282                         else if(*g_id_swb_pkc_CAs_revocation_info == *posOid)
00283                         {
00284                             //Not supported                         
00285                         }
00286                         else if(*g_idSwbPartialCertPath == *posOid)
00287                         {
00288                             partialPathWB = (*pos)->GetValue();
00289                         }
00290                         else if(*g_idSwbErsPkcCert == *posOid)
00291                         {
00292                             pkcCertWB_ER = (*pos)->GetValue();
00293                         }
00294                         else if(*g_idSwbErsBestCertPath == *posOid)
00295                         {
00296                             bestCertPathWB_ER = (*pos)->GetValue();
00297                         }
00298                         else if(*g_idSwbErsPartialCertPath == *posOid)
00299                         {
00300                             partialPathWB_ER = (*pos)->GetValue();
00301                         }
00302                         else if(*g_idSwbErsRevocationInfo == *posOid)
00303                         {
00304                             revInfoWB_ER = (*pos)->GetValue();
00305                         }
00306                         else if(*g_idSwbErsAll == *posOid)
00307                         {
00308                             ersAllWB_ER = (*pos)->GetValue();
00309                         }
00310                     }
00311 
00312                     if(!edh->m_wantBacks.empty())
00313                     {
00314                         IPKIFExtHandlerDataPtr iEdh = boost::dynamic_pointer_cast<IPKIFExtHandlerData, CPKIFReplyWantBack_ExtDataHandler>(edh);
00315                         results.SetExtHandlerData("PKIFSCVP_WantBacks", iEdh);
00316 
00317                         SetWantBacksFromResponse(edh);
00318                     }
00319 
00320                     if(bestCertPathWB && bestCertPathWB_ER)
00321                     {
00322                         VerifyCertPathWB_ER(bestCertPathWB, bestCertPathWB_ER, path, this);
00323                     }
00324                     if(partialPathWB && partialPathWB_ER)
00325                     {
00326                         VerifyPartialPathWB_ER(partialPathWB, partialPathWB_ER, path, this);
00327                     }
00328                     if(revInfoWB && revInfoWB_ER)
00329                     {
00330                         VerifyRevInfoWB_ER(revInfoWB, revInfoWB_ER, path, this);
00331                     }
00332                     if(pkcCertWB_ER)
00333                     {
00334                         CPKIFCertificatePtr targetCertWB;
00335                         CPKIFCertReferencePtr certRef = replyObject->GetCertRef();
00336                         if(CERTREFERENCES_PKC == certRef->GetCertRefType())
00337                         {
00338                             CPKIFPKCReferencePtr pkcCertRef = certRef->GetPKC();
00339                             if(REFERENCETYPE_CERT == pkcCertRef->GetRefType())
00340                                 targetCertWB = pkcCertRef->GetCert();
00341                         }
00342 
00343                         if(targetCertWB)
00344                             VerifyPKCCertWB_ER(targetCertWB, pkcCertWB_ER, path, this);
00345                     }
00346 
00347                     if(bestCertPathWB)
00348                     {
00349                         CertPathWantBackToResultsAndStores(bestCertPathWB, revInfoWB, path, this, results, this);
00350                         IPKIFTrustAnchorPtr ta;
00351                         path.GetTrustRoot(ta);
00352                         if(ta)
00353                         {
00354                             results.SetTrustAnchor(ta);
00355                         }
00356                     }
00357                 }
00358                 return true;
00359             }//if(replyObject)                                                  - If any of these three fail, return false
00360         }//if(!VerifyResponseSignature(resp, this, cvr, false, parsedResponse)) - and let next colleague try to fulfill
00361     }//if(PostRequestURL(encRequest, resp, url, PKIF_SCVP))                     - the request.
00362 
00363     return false;
00364 }

Generated on Mon Nov 15 11:15:55 2010 for PublicKeyInfrastructureFramework(PKIF) by  doxygen 1.5.6